Иконка ресурса

FREE Sirens : 2.3.0 2.3.0

Нет прав для скачивания
C#:
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Rust.Instruments;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using static BaseEntity;
using static InstrumentKeyController;

namespace Oxide.Plugins
{
	[Info("Sirens", "ZockiRR", "2.3.0")]
	[Description("Gives players the ability to attach sirens to vehicles")]
	class Sirens : CovalencePlugin
	{
		#region variables
		private const string PERMISSION_ATTACHSIRENS = "sirens.attachsirens";
		private const string PERMISSION_DETACHSIRENS = "sirens.detachsirens";
		private const string PERMISSION_ATTACHSIRENS_GLOBAL = "sirens.attachallsirens";
		private const string PERMISSION_DETACHSIRENS_GLOBAL = "sirens.detachallsirens";

		private const string I18N_MISSING_SIREN = "NoSirenForName";
		private const string I18N_COULD_NOT_ATTACH = "CouldNotAttach";
		private const string I18N_NOT_SUPPORTED = "NotSupported";
		private const string I18N_ATTACHED = "Attached";
		private const string I18N_ATTACHED_GLOBAL = "AttachedGlobal";
		private const string I18N_DETACHED = "Detached";
		private const string I18N_DETACHED_GLOBAL = "DetachedGlobal";
		private const string I18N_NOT_A_VEHICLE = "NotAVehicle";
		private const string I18N_SIRENS = "Sirens";
		private const string I18N_PLAYERS_ONLY = "PlayersOnly";

		// Initial prefabs
		private const string PREFAB_COCKPIT = "assets/content/vehicles/modularcar/module_entities/1module_cockpit.prefab";
		private const string PREFAB_COCKPIT_ARMORED = "assets/content/vehicles/modularcar/module_entities/1module_cockpit_armored.prefab";
		private const string PREFAB_COCKPIT_WITH_ENGINE = "assets/content/vehicles/modularcar/module_entities/1module_cockpit_with_engine.prefab";
		private const string PREFAB_BUTTON = "assets/prefabs/deployable/playerioents/button/button.prefab";
		private const string PREFAB_FLASHERLIGHT = "assets/prefabs/deployable/playerioents/lights/flasherlight/electric.flasherlight.deployed.prefab";
		private const string PREFAB_SIRENLIGHT = "assets/prefabs/deployable/playerioents/lights/sirenlight/electric.sirenlight.deployed.prefab";
		private const string PREFAB_SIRENLIGHT_ORANGE = "assets/prefabs/io/electric/lights/sirenlightorange.prefab";
		private const string PREFAB_SIRENLIGHT_GREEN = "assets/prefabs/io/electric/lights/sirenlightgreen.prefab";
		private const string PREFAB_SIRENLIGHT_BLUE = "assets/prefabs/io/electric/lights/sirenlightblue.prefab";
		private const string PREFAB_TRUMPET = "assets/prefabs/instruments/trumpet/trumpet.weapon.prefab";

		private const string PREFAB_SEDAN = "assets/content/vehicles/sedan_a/sedantest.entity.prefab";
		private const string PREFAB_SEDAN_RAIL = "assets/content/vehicles/sedan_a/sedanrail.entity.prefab";
		private const string PREFAB_MINICOPTER = "assets/content/vehicles/minicopter/minicopter.entity.prefab";
		private const string PREFAB_TRANSPORTHELI = "assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab";
		private const string PREFAB_RHIB = "assets/content/vehicles/boats/rhib/rhib.prefab";
		private const string PREFAB_ROWBOAT = "assets/content/vehicles/boats/rowboat/rowboat.prefab";
		private const string PREFAB_WORKCART = "assets/content/vehicles/trains/workcart/workcart.entity.prefab";
		private const string PREFAB_WORKCART_ABOVE_GROUND = "assets/content/vehicles/trains/workcart/workcart_aboveground.entity.prefab";
		private const string PREFAB_WORKCART_COVERED = "assets/content/vehicles/trains/workcart/workcart_aboveground2.entity.prefab";
		private const string PREFAB_MAGNETCRANE = "assets/content/vehicles/crane_magnet/magnetcrane.entity.prefab";
		private const string PREFAB_HORSE = "assets/content/vehicles/horse/ridablehorse.prefab";
		private const string PREFAB_ATTACKHELI = "assets/content/vehicles/attackhelicopter/attackhelicopter.entity.prefab";
		private const string PREFAB_MOTORBIKE = "assets/content/vehicles/bikes/motorbike.prefab";
		private const string PREFAB_MOTORBIKE_SIDECAR = "assets/content/vehicles/bikes/motorbike_sidecar.prefab";
		private const string PREFAB_PEDALBIKE = "assets/content/vehicles/bikes/pedalbike.prefab";
		private const string PREFAB_PEDALTRIKE = "assets/content/vehicles/bikes/pedaltrike.prefab";
		private const string PREFAB_TUGBOAT = "assets/content/vehicles/boats/tugboat/tugboat.prefab";
		private const string PREFAB_PTBOAT = "assets/content/vehicles/boats/ptboat/ptboat.prefab";
		private const string PREFAB_SNOWMOBILE = "assets/content/vehicles/snowmobiles/snowmobile.prefab";
		private const string PREFAB_SNOWMOBILE_TOMAHA = "assets/content/vehicles/snowmobiles/tomahasnowmobile.prefab";

		private const string KEY_MODULAR_CAR = "MODULAR_CAR";

		private const string DATAPATH_SIRENS = "sirens/";

		// Preconfigured sirens
		private static readonly Siren SIREN_DEFAULT = new("police-germany",
			new Dictionary<string, Attachment[]>
			{
				[PREFAB_COCKPIT] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.05f, 0.68f, 0.2f), new Vector3(200f, 0f, 0f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(-0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 1.46f, -0.9f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_COCKPIT_ARMORED] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.05f, 0.68f, 0.2f), new Vector3(200f, 0f, 0f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(-0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 1.46f, -0.9f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_COCKPIT_WITH_ENGINE] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.05f, 0.68f, 0.2f), new Vector3(200f, 0f, 0f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(-0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 1.46f, -0.9f), new Vector3(180f, 90f, 0f))
				}
			},
			new Dictionary<string, Attachment[]>
			{
				[PREFAB_SEDAN] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.0f, 1.0f, 1.32f), new Vector3(210f, 0f, 0f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(-0.4f, 1.65f, 0.2f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.4f, 1.65f, 0.2f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 1.72f, 0.2f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_SEDAN_RAIL] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.0f, 1.23f, 0.56f), new Vector3(210f, 0f, 0f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(-0.4f, 1.9f, -0.555f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.4f, 1.9f, -0.555f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 1.96f, -0.555f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_MINICOPTER] = new Attachment[] {
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 2.235f, -0.025f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 0.832f, -2.7f), new Vector3(272f, 0f, 0f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.01f, 0.82f, -0.9f), new Vector3(180f, 270f, 0f))
				},
				[PREFAB_TRANSPORTHELI] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.012f, 1.215f, 2.86f), new Vector3(242f, 0f, 0f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(-0.3f, 3.15f, -7.65f), new Vector3(0f, 0f, 90f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.1f, 3.15f, -7.65f), new Vector3(0f, 0f, 270f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 0.55f, 3.6f), new Vector3(180f, 0f, 0f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(-0.08f, 0.53f, 2.5f), new Vector3(0f, 90f, 0f))
				},
				[PREFAB_RHIB] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(-0.43f, 2.23f, 0.62f), new Vector3(210f, 0f, 0f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(-0.55f, 2.83f, 0.62f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.55f, 2.83f, 0.62f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.88f, 1.22f, 0.5f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_ROWBOAT] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(-0.5f, 0.495f, -1.8f), new Vector3(270f, 270f, 0f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 0.8f, 2.18f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.58f, 0.16f, -0.4f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_WORKCART] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.185f, 2.405f, 3.95f), new Vector3(235f, 0f, 0f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.1f, 3.93f, 4.13f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(1.25f, 3.93f, 4.13f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(-1.49f, 2.5f, -4.58f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(1.51f, 2.5f, -4.58f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.67f, 3.88f, 4.13f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_WORKCART_ABOVE_GROUND] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.185f, 2.405f, 3.95f), new Vector3(235f, 0f, 0f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.1f, 3.93f, 4.13f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(1.25f, 3.93f, 4.13f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(-1.49f, 2.5f, -4.58f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(1.51f, 2.5f, -4.58f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.67f, 3.88f, 4.13f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_WORKCART_COVERED] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.185f, 2.405f, 3.95f), new Vector3(235f, 0f, 0f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.1f, 3.93f, 4.13f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(1.25f, 3.93f, 4.13f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.67f, 3.88f, 4.13f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_MAGNETCRANE] = new Attachment[] {
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(-0.95f, 4.25f, 0.5f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 1.46f, 0.0f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_HORSE] = new Attachment[] {
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 1.8f, 1.45f), new Vector3(55f, 0f, 0f), "head"),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.1f, 1.28f, 1.74f), new Vector3(180f, 120f, 330f), "lip_lower")
				},
				[PREFAB_ATTACKHELI] = new Attachment[] {
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 2.48f, -0.3f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.1f, 2.3f, -6.5f), new Vector3(0f, 0f, 90f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.01f, 0.84f, -0.9f), new Vector3(180f, 270f, 0f))
				},
				[PREFAB_MOTORBIKE] = new Attachment[] {
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(-0.1f, 1.13f, 0.34f), new Vector3(0f, 0f, 90f), "FrontBar"),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.1f, 1.13f, 0.34f), new Vector3(0f, 0f, 270f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 0.95f, -0.8f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(-0.014f, 0.95f, 0.26f), new Vector3(186f, 89.5f, 10.4f))
				},
				[PREFAB_MOTORBIKE_SIDECAR] = new Attachment[] {
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(-0.1f, 1.13f, 0.34f), new Vector3(0f, 0f, 90f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.1f, 1.13f, 0.34f), new Vector3(0f, 0f, 270f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 0.95f, -0.8f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(1.1f, 0.64f, -0.25f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(-0.014f, 0.95f, 0.26f), new Vector3(186f, 89.5f, 10.4f))
				},
				[PREFAB_PEDALBIKE] = new Attachment[] {
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 0.85f, 0.46f), new Vector3(0f, 0f, 90f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 0.85f, 0.46f), new Vector3(0f, 0f, 270f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 0.7f, -0.275f), new Vector3(315f, 0f, 0f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(-0.016f, 0.905f, 0.264f), new Vector3(183.5f, 89.8f, 6.1f))
				},
				[PREFAB_PEDALTRIKE] = new Attachment[] {
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 0.85f, 0.46f), new Vector3(0f, 0f, 90f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 0.85f, 0.46f), new Vector3(0f, 0f, 270f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 0.8f, -1.16f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(-0.016f, 0.905f, 0.264f), new Vector3(183.5f, 89.8f, 6.1f))
				},
				[PREFAB_TUGBOAT] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(1.15f, 6.76f, 3.8f), new Vector3(-52f, 222f, 0f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 8.3f, 4.98f), new Vector3(45f, 0f, 0f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(2.88f, 3.08f, -8.08f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(-2.88f, 3.08f, -8.08f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.78f, 4.46f, 5.75f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_PTBOAT] = new Attachment[] {
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(-1.48f, 2.88f, 0.69f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(1.48f, 2.88f, 0.69f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 1.65f, 4.8f)),
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(-1.42f, 1.65f, -4.66f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 3.06f, 0.615f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_SNOWMOBILE] = new Attachment[] {
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(0.0f, 0.74f, 0.6f), new Vector3(18f, 0f, 0f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 0.6f, 0.62f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_SNOWMOBILE_TOMAHA] = new Attachment[] {
					new Attachment(PREFAB_FLASHERLIGHT, new Vector3(-0.08f, 0.66f, 0.45f), new Vector3(8f, 0f, 0f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 0.34f, 0.65f), new Vector3(180f, 90f, 0f))
				}
			}, new Tone(Notes.A, NoteType.Regular, 4, 1f), new Tone(Notes.D, NoteType.Regular, 5, 1f));
		private static readonly Siren SIREN_SILENT = new("warning-lights",
			new Dictionary<string, Attachment[]>
			{
				[PREFAB_COCKPIT] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.05f, 0.68f, 0.2f), new Vector3(200f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(-0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.4f, 1.4f, -0.9f))
				},
				[PREFAB_COCKPIT_ARMORED] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.05f, 0.68f, 0.2f), new Vector3(200f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(-0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.4f, 1.4f, -0.9f))
				},
				[PREFAB_COCKPIT_WITH_ENGINE] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.05f, 0.68f, 0.2f), new Vector3(200f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(-0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.4f, 1.4f, -0.9f))
				}
			},
			new Dictionary<string, Attachment[]>
			{
				[PREFAB_SEDAN] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.0f, 1.0f, 1.32f), new Vector3(210f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(-0.4f, 1.64f, 0.2f), new Vector3(0f, 0f, 3f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.4f, 1.64f, 0.2f), new Vector3(0f, 0f, 357f))
				},
				[PREFAB_SEDAN_RAIL] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.0f, 1.23f, 0.56f), new Vector3(210f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(-0.4f, 1.885f, -0.555f), new Vector3(0f, 0f, 3f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.4f, 1.885f, -0.555f), new Vector3(0f, 0f, 357f))
				},
				[PREFAB_MINICOPTER] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.0f, 2.235f, -0.025f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.0f, 0.832f, -2.7f), new Vector3(272f, 0f, 0f))
				},
				[PREFAB_TRANSPORTHELI] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.012f, 1.215f, 2.86f), new Vector3(242f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(-0.3f, 3.15f, -7.65f), new Vector3(0f, 0f, 90f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.1f, 3.15f, -7.65f), new Vector3(0f, 0f, 270f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.0f, 0.55f, 3.6f), new Vector3(180f, 0f, 0f))
				},
				[PREFAB_RHIB] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(-0.43f, 2.23f, 0.62f), new Vector3(210f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.0f, 1.55f, 4.15f))
				},
				[PREFAB_ROWBOAT] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(-0.5f, 0.495f, -1.8f), new Vector3(270f, 270f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.0f, 0.8f, 2.18f))
				},
				[PREFAB_WORKCART] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.185f, 2.405f, 3.95f), new Vector3(235f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(1.24f, 3.78f, 4.13f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(-1.49f, 2.5f, -4.58f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(1.51f, 2.5f, -4.58f))
				},
				[PREFAB_WORKCART_ABOVE_GROUND] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.185f, 2.405f, 3.95f), new Vector3(235f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(1.24f, 3.78f, 4.13f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(-1.49f, 2.5f, -4.58f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(1.51f, 2.5f, -4.58f))
				},
				[PREFAB_WORKCART_COVERED] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.185f, 2.405f, 3.95f), new Vector3(235f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(1.24f, 3.78f, 4.13f))
				},
				[PREFAB_MAGNETCRANE] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(-0.95f, 4.25f, 0.5f))
				},
				[PREFAB_HORSE] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.0f, 1.7f, 1.2f), new Vector3(25f, 0f, 0f), "head")
				},
				[PREFAB_ATTACKHELI] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.0f, 2.48f, -0.37f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.11f, 2.2f, -6.45f), new Vector3(0f, 0f, -90f))
				},
				[PREFAB_TUGBOAT] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(1.15f, 6.76f, 3.8f), new Vector3(-52f, 222f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.0f, 8.3f, 4.98f), new Vector3(45f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(2.88f, 3.08f, -8.08f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(-2.88f, 3.08f, -8.08f))
				},
				[PREFAB_PTBOAT] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(-1.48f, 2.88f, 0.69f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(1.48f, 2.88f, 0.69f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.0f, 1.65f, 4.8f)),
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(-1.42f, 1.65f, -4.66f))
				},
				[PREFAB_SNOWMOBILE] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(0.0f, 0.74f, 0.6f), new Vector3(18f, 0f, 0f))
				},
				[PREFAB_SNOWMOBILE_TOMAHA] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT, new Vector3(-0.08f, 0.66f, 0.45f), new Vector3(8f, 0f, 0f))
				}
			});
		private static readonly Siren SIREN_ORANGE = new("orange-lights",
			new Dictionary<string, Attachment[]>
			{
				[PREFAB_COCKPIT] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.05f, 0.68f, 0.2f), new Vector3(200f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(-0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.4f, 1.4f, -0.9f))
				},
				[PREFAB_COCKPIT_ARMORED] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.05f, 0.68f, 0.2f), new Vector3(200f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(-0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.4f, 1.4f, -0.9f))
				},
				[PREFAB_COCKPIT_WITH_ENGINE] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.05f, 0.68f, 0.2f), new Vector3(200f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(-0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.4f, 1.4f, -0.9f))
				}
			},
			new Dictionary<string, Attachment[]>
			{
				[PREFAB_SEDAN] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.0f, 1.0f, 1.32f), new Vector3(210f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(-0.4f, 1.64f, 0.2f), new Vector3(0f, 0f, 3f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.4f, 1.64f, 0.2f), new Vector3(0f, 0f, 357f))
				},
				[PREFAB_SEDAN_RAIL] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.0f, 1.23f, 0.56f), new Vector3(210f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(-0.4f, 1.885f, -0.555f), new Vector3(0f, 0f, 3f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.4f, 1.885f, -0.555f), new Vector3(0f, 0f, 357f))
				},
				[PREFAB_MINICOPTER] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.0f, 2.235f, -0.025f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.0f, 0.832f, -2.7f), new Vector3(272f, 0f, 0f))
				},
				[PREFAB_TRANSPORTHELI] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.012f, 1.215f, 2.86f), new Vector3(242f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(-0.3f, 3.15f, -7.65f), new Vector3(0f, 0f, 90f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.1f, 3.15f, -7.65f), new Vector3(0f, 0f, 270f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.0f, 0.55f, 3.6f), new Vector3(180f, 0f, 0f))
				},
				[PREFAB_RHIB] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(-0.43f, 2.23f, 0.62f), new Vector3(210f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.0f, 1.55f, 4.15f))
				},
				[PREFAB_ROWBOAT] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(-0.5f, 0.495f, -1.8f), new Vector3(270f, 270f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.0f, 0.8f, 2.18f))
				},
				[PREFAB_WORKCART] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.185f, 2.405f, 3.95f), new Vector3(235f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(1.24f, 3.78f, 4.13f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(-1.49f, 2.5f, -4.58f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(1.51f, 2.5f, -4.58f))
				},
				[PREFAB_WORKCART_ABOVE_GROUND] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.185f, 2.405f, 3.95f), new Vector3(235f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(1.24f, 3.78f, 4.13f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(-1.49f, 2.5f, -4.58f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(1.51f, 2.5f, -4.58f))
				},
				[PREFAB_WORKCART_COVERED] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.185f, 2.405f, 3.95f), new Vector3(235f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(1.24f, 3.78f, 4.13f))
				},
				[PREFAB_MAGNETCRANE] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(-0.95f, 4.25f, 0.5f))
				},
				[PREFAB_HORSE] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.0f, 1.7f, 1.2f), new Vector3(25f, 0f, 0f), "head")
				},
				[PREFAB_ATTACKHELI] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.0f, 2.48f, -0.37f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.11f, 2.2f, -6.45f), new Vector3(0f, 0f, -90f))
				},
				[PREFAB_TUGBOAT] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(1.15f, 6.76f, 3.8f), new Vector3(-52f, 222f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.0f, 8.3f, 4.98f), new Vector3(45f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(2.88f, 3.08f, -8.08f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(-2.88f, 3.08f, -8.08f))
				},
				[PREFAB_PTBOAT] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(-1.48f, 2.88f, 0.69f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(1.48f, 2.88f, 0.69f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.0f, 1.65f, 4.8f)),
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(-1.42f, 1.65f, -4.66f))
				},
				[PREFAB_SNOWMOBILE] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(0.0f, 0.74f, 0.6f), new Vector3(18f, 0f, 0f))
				},
				[PREFAB_SNOWMOBILE_TOMAHA] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_ORANGE, new Vector3(-0.08f, 0.66f, 0.45f), new Vector3(8f, 0f, 0f))
				}
			});
		private static readonly Siren SIREN_GREEN = new("green-lights",
			new Dictionary<string, Attachment[]>
			{
				[PREFAB_COCKPIT] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.05f, 0.68f, 0.2f), new Vector3(200f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(-0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.4f, 1.4f, -0.9f))
				},
				[PREFAB_COCKPIT_ARMORED] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.05f, 0.68f, 0.2f), new Vector3(200f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(-0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.4f, 1.4f, -0.9f))
				},
				[PREFAB_COCKPIT_WITH_ENGINE] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.05f, 0.68f, 0.2f), new Vector3(200f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(-0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.4f, 1.4f, -0.9f))
				}
			},
			new Dictionary<string, Attachment[]>
			{
				[PREFAB_SEDAN] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.0f, 1.0f, 1.32f), new Vector3(210f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(-0.4f, 1.64f, 0.2f), new Vector3(0f, 0f, 3f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.4f, 1.64f, 0.2f), new Vector3(0f, 0f, 357f))
				},
				[PREFAB_SEDAN_RAIL] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.0f, 1.23f, 0.56f), new Vector3(210f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(-0.4f, 1.885f, -0.555f), new Vector3(0f, 0f, 3f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.4f, 1.885f, -0.555f), new Vector3(0f, 0f, 357f))
				},
				[PREFAB_MINICOPTER] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.0f, 2.235f, -0.025f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.0f, 0.832f, -2.7f), new Vector3(272f, 0f, 0f))
				},
				[PREFAB_TRANSPORTHELI] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.012f, 1.215f, 2.86f), new Vector3(242f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(-0.3f, 3.15f, -7.65f), new Vector3(0f, 0f, 90f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.1f, 3.15f, -7.65f), new Vector3(0f, 0f, 270f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.0f, 0.55f, 3.6f), new Vector3(180f, 0f, 0f))
				},
				[PREFAB_RHIB] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(-0.43f, 2.23f, 0.62f), new Vector3(210f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.0f, 1.55f, 4.15f))
				},
				[PREFAB_ROWBOAT] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(-0.5f, 0.495f, -1.8f), new Vector3(270f, 270f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.0f, 0.8f, 2.18f))
				},
				[PREFAB_WORKCART] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.185f, 2.405f, 3.95f), new Vector3(235f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(1.24f, 3.78f, 4.13f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(-1.49f, 2.5f, -4.58f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(1.51f, 2.5f, -4.58f))
				},
				[PREFAB_WORKCART_ABOVE_GROUND] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.185f, 2.405f, 3.95f), new Vector3(235f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(1.24f, 3.78f, 4.13f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(-1.49f, 2.5f, -4.58f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(1.51f, 2.5f, -4.58f))
				},
				[PREFAB_WORKCART_COVERED] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.185f, 2.405f, 3.95f), new Vector3(235f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(1.24f, 3.78f, 4.13f))
				},
				[PREFAB_MAGNETCRANE] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(-0.95f, 4.25f, 0.5f))
				},
				[PREFAB_HORSE] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.0f, 1.7f, 1.2f), new Vector3(25f, 0f, 0f), "head")
				},
				[PREFAB_ATTACKHELI] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.0f, 2.48f, -0.37f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.11f, 2.2f, -6.45f), new Vector3(0f, 0f, -90f))
				},
				[PREFAB_TUGBOAT] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(1.15f, 6.76f, 3.8f), new Vector3(-52f, 222f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.0f, 8.3f, 4.98f), new Vector3(45f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(2.88f, 3.08f, -8.08f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(-2.88f, 3.08f, -8.08f))
				},
				[PREFAB_PTBOAT] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(-1.48f, 2.88f, 0.69f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(1.48f, 2.88f, 0.69f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.0f, 1.65f, 4.8f)),
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(-1.42f, 1.65f, -4.66f))
				},
				[PREFAB_SNOWMOBILE] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(0.0f, 0.74f, 0.6f), new Vector3(18f, 0f, 0f))
				},
				[PREFAB_SNOWMOBILE_TOMAHA] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_GREEN, new Vector3(-0.08f, 0.66f, 0.45f), new Vector3(8f, 0f, 0f))
				}
			});
		private static readonly Siren SIREN_BLUE = new("blue-sirens",
			new Dictionary<string, Attachment[]>
			{
				[PREFAB_COCKPIT] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.05f, 0.68f, 0.2f), new Vector3(200f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(-0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 1.46f, -0.9f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_COCKPIT_ARMORED] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.05f, 0.68f, 0.2f), new Vector3(200f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(-0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 1.46f, -0.9f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_COCKPIT_WITH_ENGINE] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.05f, 0.68f, 0.2f), new Vector3(200f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(-0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.4f, 1.4f, -0.9f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 1.46f, -0.9f), new Vector3(180f, 90f, 0f))
				}
			},
			new Dictionary<string, Attachment[]>
			{
				[PREFAB_SEDAN] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.0f, 1.0f, 1.32f), new Vector3(210f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(-0.4f, 1.64f, 0.2f), new Vector3(0f, 0f, 3f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.4f, 1.64f, 0.2f), new Vector3(0f, 0f, 357f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 1.72f, 0.2f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_SEDAN_RAIL] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.0f, 1.23f, 0.56f), new Vector3(210f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(-0.4f, 1.885f, -0.555f), new Vector3(0f, 0f, 3f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.4f, 1.885f, -0.555f), new Vector3(0f, 0f, 357f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 1.96f, -0.555f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_MINICOPTER] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.0f, 2.235f, -0.025f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.0f, 0.832f, -2.7f), new Vector3(272f, 0f, 0f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.01f, 0.82f, -0.9f), new Vector3(180f, 270f, 0f))
				},
				[PREFAB_TRANSPORTHELI] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.012f, 1.215f, 2.86f), new Vector3(242f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(-0.3f, 3.15f, -7.65f), new Vector3(0f, 0f, 90f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.1f, 3.15f, -7.65f), new Vector3(0f, 0f, 270f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.0f, 0.55f, 3.6f), new Vector3(180f, 0f, 0f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(-0.08f, 0.53f, 2.5f), new Vector3(0f, 90f, 0f))
				},
				[PREFAB_RHIB] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(-0.43f, 2.23f, 0.62f), new Vector3(210f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.0f, 1.55f, 4.15f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.88f, 1.22f, 0.5f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_ROWBOAT] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(-0.5f, 0.495f, -1.8f), new Vector3(270f, 270f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.0f, 0.8f, 2.18f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.58f, 0.16f, -0.4f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_WORKCART] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.185f, 2.405f, 3.95f), new Vector3(235f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(1.24f, 3.78f, 4.13f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(-1.49f, 2.5f, -4.58f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(1.51f, 2.5f, -4.58f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.67f, 3.88f, 4.13f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_WORKCART_ABOVE_GROUND] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.185f, 2.405f, 3.95f), new Vector3(235f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(1.24f, 3.78f, 4.13f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(-1.49f, 2.5f, -4.58f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(1.51f, 2.5f, -4.58f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.67f, 3.88f, 4.13f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_WORKCART_COVERED] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(0.185f, 2.405f, 3.95f), new Vector3(235f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(1.24f, 3.78f, 4.13f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.67f, 3.88f, 4.13f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_MAGNETCRANE] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(-0.95f, 4.25f, 0.5f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 1.46f, 0.0f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_HORSE] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.0f, 1.7f, 1.2f), new Vector3(25f, 0f, 0f), "head"),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.1f, 1.28f, 1.74f), new Vector3(180f, 120f, 330f), "lip_lower")
				},
				[PREFAB_ATTACKHELI] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.0f, 2.48f, -0.37f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.11f, 2.2f, -6.45f), new Vector3(0f, 0f, -90f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.01f, 0.84f, -0.9f), new Vector3(180f, 270f, 0f))
				},
				[PREFAB_TUGBOAT] = new Attachment[] {
					new Attachment(PREFAB_BUTTON, new Vector3(1.15f, 6.76f, 3.8f), new Vector3(-52f, 222f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.0f, 8.3f, 4.98f), new Vector3(45f, 0f, 0f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(2.88f, 3.08f, -8.08f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(-2.88f, 3.08f, -8.08f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.78f, 4.46f, 5.75f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_PTBOAT] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(-1.48f, 2.88f, 0.69f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(1.48f, 2.88f, 0.69f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.0f, 1.65f, 4.8f)),
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(-1.42f, 1.65f, -4.66f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 3.06f, 0.615f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_SNOWMOBILE] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(0.0f, 0.74f, 0.6f), new Vector3(18f, 0f, 0f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 0.6f, 0.62f), new Vector3(180f, 90f, 0f))
				},
				[PREFAB_SNOWMOBILE_TOMAHA] = new Attachment[] {
					new Attachment(PREFAB_SIRENLIGHT_BLUE, new Vector3(-0.08f, 0.66f, 0.45f), new Vector3(8f, 0f, 0f)),
					new Attachment(PREFAB_TRUMPET, new Vector3(0.0f, 0.34f, 0.65f), new Vector3(180f, 90f, 0f))
				}
			}, new Tone(Notes.A, NoteType.Regular, 4, 1f), new Tone(Notes.D, NoteType.Regular, 5, 1f));
		#endregion variables

		#region data
		private class DataContainer
		{
			// Map BaseVehicle.net.ID -> SirenInfos
			public Dictionary<ulong, VehicleContainer> VehicleSirenMap = new();
		}

		private class VehicleContainer
		{
			public string SirenName = SIREN_DEFAULT.Name;
			public SirenController.States State = SirenController.States.OFF;
			public HashSet<ulong> NetIDs = new();

			public VehicleContainer()
			{
			}

			public VehicleContainer(string aSirenName, SirenController.States aState, IEnumerable<NetworkableId> someNetIDs)
			{
				SirenName = aSirenName;
				State = aState;
				NetIDs.UnionWith(someNetIDs.Select(eachNetID => eachNetID.Value));
			}
		}
		#endregion data

		#region configuration
		private Configuration config;
		private IDictionary<string, Siren> SirenDictionary { get; } = new Dictionary<string, Siren>();

		private class Configuration
		{
			[JsonProperty("MountNeeded")]
			public bool MountNeeded = true;

			[JsonProperty("SoundEnabled")]
			public bool SoundEnabled = true;

			[JsonProperty("SirenSpawnProbability")]
			public Dictionary<string, float> SirenSpawnProbability = new()
			{
				[KEY_MODULAR_CAR] = 0f,
				[PREFAB_HORSE] = 0f,
				[PREFAB_MAGNETCRANE] = 0f,
				[PREFAB_MINICOPTER] = 0f,
				[PREFAB_RHIB] = 0f,
				[PREFAB_ROWBOAT] = 0f,
				[PREFAB_SEDAN] = 0f,
				[PREFAB_SEDAN_RAIL] = 0f,
				[PREFAB_TRANSPORTHELI] = 0f,
				[PREFAB_WORKCART] = 0f,
				[PREFAB_WORKCART_ABOVE_GROUND] = 0f,
				[PREFAB_WORKCART_COVERED] = 0f
			};

			[JsonConverter(typeof(StringEnumConverter))]
			[JsonProperty("DefaultState")]
			public SirenController.States DefaultState = SirenController.States.OFF;

			public string ToJson() => JsonConvert.SerializeObject(this);

			public Dictionary<string, object> ToDictionary() => JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
		}

		private class Tone
		{
			public Tone(Notes aNote = Notes.A, NoteType aNoteType = NoteType.Regular, int anOctave = 4, float aDuration = 1f)
			{
				Note = aNote;
				NoteType = aNoteType;
				Octave = anOctave;
				Duration = aDuration;
			}

			[JsonConverter(typeof(StringEnumConverter))]
			[JsonProperty("Note")]
			public Notes Note;

			[JsonConverter(typeof(StringEnumConverter))]
			[JsonProperty("NoteType")]
			public NoteType NoteType;

			[JsonProperty("Octave")]
			public int Octave;

			[JsonProperty("Duration")]
			public float Duration;

			public string ToJson() => JsonConvert.SerializeObject(this);

			public Dictionary<string, object> ToDictionary() => JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
		}

		private class Siren
		{
			public Siren(string aName, Dictionary<string, Attachment[]> someModules, Dictionary<string, Attachment[]> someVehicles, params Tone[] someTones)
			{
				Name = aName;
				Modules = someModules;
				Vehicles = someVehicles;
				Tones = someTones;
			}

			[JsonProperty("Name")]
			public string Name;

			[JsonProperty("Tones")]
			public Tone[] Tones;

			[JsonProperty("Modules")]
			public Dictionary<string, Attachment[]> Modules;

			[JsonProperty("Vehicles")]
			public Dictionary<string, Attachment[]> Vehicles;

			public string ToJson() => JsonConvert.SerializeObject(this);

			public Dictionary<string, object> ToDictionary() => JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
		}

		private class Attachment
		{
			public Attachment(string aPrefab, Vector3 aPosition, Vector3 anAngle = new Vector3(), string aBone = null)
			{
				Prefab = aPrefab;
				Position = aPosition;
				Angle = anAngle;
				Bone = aBone;
			}

			[JsonProperty("Prefab")]
			public string Prefab;

			[JsonProperty("Position")]
			public Vector3 Position;

			[JsonProperty("Angle")]
			public Vector3 Angle;

			[JsonProperty("Bone")]
			public string Bone;

			public string ToJson() => JsonConvert.SerializeObject(this);

			public Dictionary<string, object> ToDictionary() => JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
		}

		protected override void LoadDefaultConfig()
		{
			config = new Configuration();
			SirenDictionary.Clear();
			SirenDictionary.Add(SIREN_DEFAULT.Name, SIREN_DEFAULT);
			SirenDictionary.Add(SIREN_SILENT.Name, SIREN_SILENT);
			SirenDictionary.Add(SIREN_ORANGE.Name, SIREN_ORANGE);
			SirenDictionary.Add(SIREN_GREEN.Name, SIREN_GREEN);
			SirenDictionary.Add(SIREN_BLUE.Name, SIREN_BLUE);
		}

		protected override void LoadConfig()
		{
			base.LoadConfig();
			try
			{
				config = Config.ReadObject<Configuration>();
				if (config == null)
				{
					throw new JsonException();
				}

				SaveDefaultSirens();
				try
				{
					foreach (string eachSirenFile in Interface.Oxide.DataFileSystem.GetFiles(DATAPATH_SIRENS, "*.json"))
					{
						string theFilename = eachSirenFile.Basename(".json");
						try
						{
							Siren theSiren = Interface.Oxide.DataFileSystem.ReadObject<Siren>(DATAPATH_SIRENS + theFilename);
							SirenDictionary.Add(theSiren.Name, theSiren);
						}
						catch
						{
							PrintWarning($"Siren file {theFilename}.json is invalid; ignoring");
						}
					}
				}
				catch
				{

				}
				Puts("Loaded sirens: " + string.Join(", ", SirenDictionary.Keys));


				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);
		}

		protected void SaveDefaultSirens()
		{
			PrintWarning($"Saved default sirens");
			Interface.Oxide.DataFileSystem.WriteObject(DATAPATH_SIRENS + SIREN_DEFAULT.Name, SIREN_DEFAULT);
			Interface.Oxide.DataFileSystem.WriteObject(DATAPATH_SIRENS + SIREN_SILENT.Name, SIREN_SILENT);
			Interface.Oxide.DataFileSystem.WriteObject(DATAPATH_SIRENS + SIREN_ORANGE.Name, SIREN_ORANGE);
			Interface.Oxide.DataFileSystem.WriteObject(DATAPATH_SIRENS + SIREN_GREEN.Name, SIREN_GREEN);
			Interface.Oxide.DataFileSystem.WriteObject(DATAPATH_SIRENS + SIREN_BLUE.Name, SIREN_BLUE);
		}
		#endregion configuration

		#region localization
		protected override void LoadDefaultMessages()
		{
			lang.RegisterMessages(new Dictionary<string, string>
			{
				[I18N_MISSING_SIREN] = "No siren was found for the given name (using {0} instead)",
				[I18N_COULD_NOT_ATTACH] = "Could not attach '{0}'",
				[I18N_ATTACHED] = "Attached siren '{0}'",
				[I18N_ATTACHED_GLOBAL] = "Attached siren '{0}' to all existing cars",
				[I18N_DETACHED] = "Detached siren",
				[I18N_DETACHED_GLOBAL] = "Detached all existing sirens",
				[I18N_NOT_A_VEHICLE] = "This entity is not a (supported) vehicle",
				[I18N_SIRENS] = "Available sirens: {0}",
				[I18N_PLAYERS_ONLY] = "Command '{0}' can only be used by a player",
				[I18N_NOT_SUPPORTED] = "The siren '{0}' has no configuration for '{1}'"
			}, this);
		}
		#endregion localization

		#region commands
		[Command("attachsirens"), Permission(PERMISSION_ATTACHSIRENS)]
		private void AttachCarSirens(IPlayer aPlayer, string aCommand, string[] someArgs)
		{
			if (aPlayer.IsServer)
			{
				Message(aPlayer, I18N_PLAYERS_ONLY, aCommand);
				return;
			}

			BaseVehicle theVehicle = RaycastVehicle(aPlayer);
			if (theVehicle)
			{
				Siren theSiren = someArgs.Length > 0 ? FindSirenForName(someArgs[0], aPlayer) : SirenDictionary.Values.First();
				if (AttachSirens(theVehicle, theSiren, config.DefaultState, aPlayer))
				{
					Message(aPlayer, I18N_ATTACHED, theSiren.Name);
				}
			}
		}

		[Command("detachsirens"), Permission(PERMISSION_DETACHSIRENS)]
		private void DetachCarSirens(IPlayer aPlayer, string aCommand, string[] _)
		{
			if (aPlayer.IsServer)
			{
				Message(aPlayer, I18N_PLAYERS_ONLY, aCommand);
				return;
			}

			BaseVehicle theVehicle = RaycastVehicle(aPlayer);
			if (theVehicle && DetachSirens(theVehicle))
			{
				Message(aPlayer, I18N_DETACHED);
			}
		}

		[Command("attachallsirens"), Permission(PERMISSION_ATTACHSIRENS_GLOBAL)]
		private void AttachAllCarSirens(IPlayer aPlayer, string _, string[] someArgs)
		{
			Siren theSiren = someArgs.Length > 0 ? FindSirenForName(someArgs[0], aPlayer) : SirenDictionary.Values.First();
			bool theAtLeastOneSuccessful = false;
			foreach (BaseVehicle eachVehicle in BaseNetworkable.serverEntities.OfType<BaseVehicle>())
			{
				theAtLeastOneSuccessful |= AttachSirens(eachVehicle, theSiren, config.DefaultState, aPlayer);
			}
			if (theAtLeastOneSuccessful)
			{
				Message(aPlayer, I18N_ATTACHED_GLOBAL, theSiren.Name);
			}
		}

		[Command("detachallsirens"), Permission(PERMISSION_DETACHSIRENS_GLOBAL)]
		private void DetachAllCarSirens(IPlayer aPlayer, string _, string[] _1)
		{
			foreach (BaseVehicle eachVehicle in BaseNetworkable.serverEntities.OfType<BaseVehicle>())
			{
				DetachSirens(eachVehicle);
			}
			Message(aPlayer, I18N_DETACHED_GLOBAL);
		}

		[Command("listsirens")]
		private void ListSirens(IPlayer aPlayer, string _, string[] _1)
		{
			Message(aPlayer, I18N_SIRENS, string.Join(", ", SirenDictionary.Keys));
		}

		[Command("togglesirens")]
		private void ToggleSirens(IPlayer aPlayer, string aCommand, string[] _)
		{
			if (aPlayer.IsServer)
			{
				Message(aPlayer, I18N_PLAYERS_ONLY, aCommand);
				return;
			}


// ... [Code preview truncated due to length. Full source in attached file] ...

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху