C#:
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Oxide.Plugins {
[Info("VehicleAirdrops", "Nikedemos", VERSION)]
[Description("Adds new types of airdrops and supply signals")]
public class VehicleAirdrops : RustPlugin {
#region META
public const string VERSION = "1.0.8";
public const string PREFAB_FIREWORK_BLUE = "assets/prefabs/deployable/fireworks/mortarblue.prefab";
public const string PREFAB_FIREWORK_CHAMPAGNE = "assets/prefabs/deployable/fireworks/mortarchampagne.prefab";
public const string PREFAB_FIREWORK_GREEN = "assets/prefabs/deployable/fireworks/mortargreen.prefab";
public const string PREFAB_FIREWORK_ORANGE = "assets/prefabs/deployable/fireworks/mortarorange.prefab";
public const string PREFAB_FIREWORK_VIOLET = "assets/prefabs/deployable/fireworks/mortarviolet.prefab";
public const string PREFAB_FIREWORK_RED = "assets/prefabs/deployable/fireworks/mortarred.prefab";
public const string PREFAB_ROMAN_BLUE = "assets/prefabs/deployable/fireworks/romancandle-blue.prefab";
public const string PREFAB_ROMAN_GREEN = "assets/prefabs/deployable/fireworks/romancandle-green.prefab";
public const string PREFAB_ROMAN_VIOLET = "assets/prefabs/deployable/fireworks/romancandle-violet.prefab";
public const string PREFAB_ROMAN_RED = "assets/prefabs/deployable/fireworks/romancandle.prefab";
#endregion
#region LANG
public static string MSG(string msg, string userID = null, params object[] args) {
if (args == null) {
return Instance.lang.GetMessage(msg, Instance, userID);
}
else {
return string.Format(Instance.lang.GetMessage(msg, Instance, userID), args);
}
}
public const string MSG_DROP_NAME_CAR = "MSG_DROP_NAME_CAR";
public const string MSG_DROP_NAME_CARS = "MSG_DROP_NAME_CARS";
public const string MSG_NO_PERMISSION = "MSG_NO_PERMISSION";
public const string MSG_DROP_NAME_NORMAL = "MSG_DROP_NAME_NORMAL";
public const string MSG_DROP_NAME_MINICOPTER = "MSG_DROP_NAME_MINICOPTER";
public const string MSG_DROP_NAME_MINICOPTERS = "MSG_DROP_NAME_MINICOPTERS";
public const string MSG_DROP_NAME_SCRAPHELI = "MSG_DROP_NAME_SCRAPHELI";
public const string MSG_DROP_NAME_SCRAPHELIS = "MSG_DROP_NAME_SCRAPHELIS";
public const string MSG_DROP_NAME_ROWBOAT = "MSG_DROP_NAME_ROWBOAT";
public const string MSG_DROP_NAME_ROWBOATS = "MSG_DROP_NAME_ROWBOATS";
public const string MSG_DROP_NAME_RHIB = "MSG_DROP_NAME_RHIB";
public const string MSG_DROP_NAME_RHIBS = "MSG_DROP_NAME_RHIBS";
public const string MSG_DROP_NAME_CRATE = "MSG_DROP_NAME_CRATE";
public const string MSG_DROP_NAME_CRATES = "MSG_DROP_NAME_CRATES";
public const string MSG_DROP_NAME_SOLO_SUB = "MSG_DROP_NAME_SOLO_SUB";
public const string MSG_DROP_NAME_DUO_SUB = "MSG_DROP_NAME_DUO_SUB";
public const string MSG_DROP_NAME_SOLO_SUBS = "MSG_DROP_NAME_SOLO_SUBS";
public const string MSG_DROP_NAME_DUO_SUBS = "MSG_DROP_NAME_DUO_SUBS";
public const string MSG_PLEASE_WAIT_TILL_LANDS = "MSG_PLEASE_WAIT_TILL_LANDS";
public const string MSG_PLEASE_WAIT_TILL_X_LANDS = "MSG_PLEASE_WAIT_TILL_X_LANDS";
public const string MSG_UNLOCK_AFTER = "MSG_UNLOCK_AFTER";
public const string MSG_BELONGS_TO_SOMEONE_ELSE = "MSG_BELONGS_TO_SOMEONE_ELSE";
public const string MSG_WILL_UNLOCK_IN = "MSG_WILL_UNLOCK_IN";
public const string MSG_VABUY_DISABLED = "MSG_VABUY_DISABLED";
public const string MSG_VABUY_COST = "MSG_VABUY_COST";
public const string MSG_VABUY_NO_SIGNALS = "MSG_VABUY_NO_SIGNALS";
public const string MSG_VABUY_YOU_JUST_BOUGHT = "MSG_VABUY_YOU_JUST_BOUGHT";
public const string MSG_VABUY_ECONOMICS_CURRENCY = "MSG_VABUY_ECONOMICS_CURRENCY";
public const string MSG_VABUY_SERVER_REWARDS_CURRENCY = "MSG_VABUY_SERVER_REWARDS_CURRENCY";
public const string MSG_VABUY_YOU_CAN_BUY = "MSG_VABUY_YOU_CAN_BUY";
public const string MSG_VABUY_YOU_CANT_BUY = "MSG_VABUY_YOU_CANT_BUY";
public const string MSG_VABUY_WRONG_DROP = "MSG_VABUY_WRONG_DROP";
public const string MSG_YOU_GAVE_SIGNAL_TO_SOMEONE = "MSG_YOU_GAVE_SIGNAL_TO_SOMEONE";
public const string MSG_YOU_RECEIVED_SIGNAL = "MSG_YOU_RECEIVED_SIGNAL";
public const string MSG_YOU_GAVE_YOURSELF = "MSG_YOU_GAVE_YOURSELF";
public const string MSG_THIS_KIND_DOESNT_EXIST = "MSG_THIS_KIND_DOESNT_EXIST";
public const string MSG_PLEASE_SPECIFY = "MSG_PLEASE_SPECIFY_NEW";
public const string MSG_YOU_HAVE_DROPPED = "MSG_YOU_HAVE_DROPPED";
public const string MSG_DIRECTION_ABOVE = "MSG_DIRECTION_ABOVE";
public const string MSG_DIRECTION_BELOW = "MSG_DIRECTION_BELOW";
public const string MSG_ANNOUNCE_MESSAGE_FORMAT_KIND = "MSG_ANNOUNCE_MESSAGE_FORMAT_KIND";
public const string MSG_ANNOUNCE_MESSAGE_FULL = "MSG_ANNOUNCE_MESSAGE_FULL";
public const string MSG_ANNOUNCE_MESSAGE_FULL_PRIVATE = "MSG_ANNOUNCE_MESSAGE_FULL_PRIVATE";
public const string MSG_NOT_ENOUGH_INVENTORY_SPACE = "MSG_NOT_ENOUGH_INVENTORY_SPACE";
public static Dictionary<string, string> LangMessages = new Dictionary<string, string> {
[MSG_DROP_NAME_CAR]
= "Modular Car", [MSG_DROP_NAME_CARS] = "Modular Cars", [MSG_NO_PERMISSION] = "You don't have permission to use this command", [MSG_DROP_NAME_NORMAL] = "Normal Drop", [MSG_DROP_NAME_MINICOPTER] = "Minicopter", [MSG_DROP_NAME_MINICOPTERS] = "Minicopters", [MSG_DROP_NAME_SCRAPHELI] = "Scrapheli", [MSG_DROP_NAME_SCRAPHELIS] = "Scraphelis", [MSG_DROP_NAME_ROWBOAT] = "Rowboat", [MSG_DROP_NAME_ROWBOATS] = "Rowboats", [MSG_DROP_NAME_RHIB] = "RHIB", [MSG_DROP_NAME_RHIBS] = "RHIBs", [MSG_DROP_NAME_CRATE] = "Codelock Crate", [MSG_DROP_NAME_CRATES] = "Codelock Crates", [MSG_DROP_NAME_DUO_SUB] = "Duo Sub", [MSG_DROP_NAME_SOLO_SUB] = "Solo Sub", [MSG_DROP_NAME_DUO_SUBS] = "Duo Subs", [MSG_DROP_NAME_SOLO_SUBS] = "Solo Subs", [MSG_PLEASE_WAIT_TILL_LANDS] = "Please wait till the drop lands.", [MSG_PLEASE_WAIT_TILL_X_LANDS] = "Please wait till the {0} lands.", [MSG_UNLOCK_AFTER] = "After it lands, it will unlock for all players in {0} seconds.", [MSG_BELONGS_TO_SOMEONE_ELSE] = "This drop belongs to someone else.", [MSG_WILL_UNLOCK_IN] = "It will unlock in {0} seconds.", [MSG_VABUY_DISABLED] = "The chat command shop is currently disabled on the server.", [MSG_VABUY_COST] = "<color=green>/vabuy</color> <color=yellow>{0}</color> <i>COST: <color=red>{1}</color></i>", [MSG_VABUY_NO_SIGNALS] = "<color=red>There's no supply signals available to buy through this command.</color>", [MSG_VABUY_YOU_JUST_BOUGHT] = "<color=green>You just bought a</color> <color=yellow>{0}</color> Supply Signal.", [MSG_VABUY_ECONOMICS_CURRENCY] = "¤", [MSG_VABUY_SERVER_REWARDS_CURRENCY] = "RP", [MSG_VABUY_YOU_CAN_BUY] = "You can buy these supply signals with <color=red>{0}</color> (you currently have <color=red>{1}</color>):", [MSG_VABUY_YOU_CANT_BUY] = "<color=red>You can't buy a</color> <color=yellow>{0}</color> <color=red>Supply Signal - either you can't afford it or don't have the permission.</color> Type <color=green>/vabuy</color> to see if there's anything else you can purchase.", [MSG_VABUY_WRONG_DROP] = "<color=red>Wrong kind of drop.</color> Type <color=green>/vabuy</color> to get the full list of names and prices.", [MSG_YOU_GAVE_SIGNAL_TO_SOMEONE] = "You have given {0} a <color=yellow>{1}</color> Supply Signal", [MSG_YOU_RECEIVED_SIGNAL] = "You have received a <color=yellow>{0}</color> Supply Signal from an admin", [MSG_YOU_GAVE_YOURSELF] = "You gave yourself a <color=yellow>{0}</color> Supply Signal.", [MSG_THIS_KIND_DOESNT_EXIST] = "This kind doesn't exist.", [MSG_PLEASE_SPECIFY] = "Please specify the kind: <color=yellow>random</color>, <color=yellow>minicopter</color>, <color=yellow>scrapheli</color>, <color=yellow>rowboat</color>, <color=yellow>rhib</color>, <color=yellow>car</color>, <color=yellow>solosub</color>, <color=yellow>duosub</color> or <color=yellow>crate</color>.", [MSG_YOU_HAVE_DROPPED] = "You have spawned a <color=yellow>{0}</color> drop {1}m {2} where you are.", [MSG_DIRECTION_ABOVE] = "above", [MSG_DIRECTION_BELOW] = "below", [MSG_ANNOUNCE_MESSAGE_FORMAT_KIND] = "<color=yellow>{0}</color>", [MSG_ANNOUNCE_MESSAGE_FULL] = "Cargo Plane with a {0} drop inbound!", [MSG_ANNOUNCE_MESSAGE_FULL_PRIVATE] = "Cargo Plane with a {0} drop inbound! <color=red>(PRIVATE, unlocks after {1}s)</color>", [MSG_NOT_ENOUGH_INVENTORY_SPACE] = "You don't have enough space in your inventory.",
}
;
#endregion
#region 3RD PARTY
[PluginReference]
private Plugin ServerRewards;
[PluginReference]
private Plugin Economics;
#endregion
#region ImageLibrary
/*
[PluginReference] private Plugin ImageLibrary;
public string GetImage(string name)
{
string cached = (string)ImageLibrary?.Call("GetImage", GetNameFromURL(name));
if (cached == null)
{
return ParseURL(name);
}
else return cached;
}
public void AddImage(string name)
{
if (!(bool)ImageLibrary.Call("HasImage", GetNameFromURL(name), (ulong)ResourceId))
{
ImageLibrary.Call("AddImage", name, GetNameFromURL(name), (ulong)ResourceId, new Action(DoneLoadingImage));
}
else
{
DoneLoadingImage();
}
}
public static string GetNameFromURL(string url)
{
var splitted = url.Split('/');
var endUrl = splitted[splitted.Length - 1];
var name = endUrl.Split('.')[0];
return name;
}
public static string ParseURL(string url)
{
var ret = $"{System.Text.Encoding.UTF8.GetString(System.Convert.FromBase64String(HTTPS))}{url}";
return ret;
}
public void LoadImages()
{
if (ImageLibrary != null)
{
AddImage(ParseURL("https://i.imgur.com/1unAPZK.png"));
}
}*/
public void DoneLoadingImage() {
Instance.PrintWarning("Loading GUI...");
GUI = new GuiManager();
}
#endregion
#region PERMISSIONS
public static readonly string PERMISSION_ADMIN = "vehicleairdrops.admin";
public static readonly string PERMISSION_VIP = "vehicleairdrops.vip";
public bool HasPermission(BasePlayer player, string permissionName) {
if (player?.net?.connection?.authLevel > 0) return true;
return permission.UserHasPermission(player.UserIDString, permissionName);
}
#endregion
#region STATIC
private static VehicleAirdrops Instance;
public static LayerMask CollisionLayer = LayerMask.GetMask("Water", "Tree", "Debris", "Clutter", "Default", "Resource", "Construction", "Terrain", "World", "Deployed");
public static Dictionary<int, string> ItemIDtoItemName = new Dictionary<int, string> {
[1553078977]
= "bleach", [1776460938] = "blood", [1401987718] = "ducttape", [-1899491405] = "glue", [642482233] = "sticks", [-1779183908] = "paper", [-751151717] = "chickenspoiled", [-1167031859] = "wolfmeatspoiled", [656371026] = "carburetor3", [1158340332] = "crankshaft3", [1883981800] = "pistons3", [1072924620] = "sparkplugs3", [-1802083073] = "valves3", [656371027] = "carburetor2", [1158340331] = "crankshaft2", [1883981801] = "pistons2", [-493159321] = "sparkplugs2", [926800282] = "valves2", [656371028] = "carburetor1", [1158340334] = "crankshaft1", [1883981798] = "pistons1", [-89874794] = "sparkplugs1", [1330084809] = "valves1",
}
;
//BOTH I4 AND V8 ENGINES
public static readonly int MODULAR_SLOT_CRANKSHAFT = 0;
public static readonly int MODULAR_SLOT_CARBURETOR = 1;
public static readonly int MODULAR_SLOT_SPARKPLUGS_A = 2;
public static readonly int MODULAR_SLOT_VALVES_A = 3;
public static readonly int MODULAR_SLOT_PISTONS_A = 4;
//ONLY THE V8 ENGINE HAS THOSE
public static readonly int MODULAR_SLOT_SPARKPLUGS_B = 5;
public static readonly int MODULAR_SLOT_VALVES_B = 6;
public static readonly int MODULAR_SLOT_PISTONS_B = 7;
public static Dictionary<string, int> ItemNameToItemID = new Dictionary<string, int> {
["bleach"]
= 1553078977, ["blood"] = 1776460938, ["ducttape"] = 1401987718, ["glue"] = -1899491405, ["sticks"] = 642482233, ["paper"] = -1779183908, ["chickenspoiled"] = -751151717, ["wolfmeatspoiled"] = -1167031859, ["carburetor3"] = 656371026, ["crankshaft3"] = 1158340332, ["pistons3"] = 1883981800, ["sparkplugs3"] = 1072924620, ["valves3"] = -1802083073, ["carburetor2"] = 656371027, ["crankshaft2"] = 1158340331, ["pistons2"] = 1883981801, ["sparkplugs2"] = -493159321, ["valves2"] = 926800282, ["carburetor1"] = 656371028, ["crankshaft1"] = 1158340334, ["pistons1"] = 1883981798, ["sparkplugs1"] = -89874794, ["valves1"] = 1330084809
}
;
public static Dictionary<string, string> KindToFakeItemName = new Dictionary<string, string> {
["minicopter"]
= "bleach", ["scrapheli"] = "blood", ["rowboat"] = "ducttape", ["rhib"] = "glue", ["car"] = "sticks", ["crate"] = "paper", ["solosub"] = "chickenspoiled", ["duosub"] = "wolfmeatspoiled"
}
;
public static Dictionary<string, string> FakeItemNameToKind = new Dictionary<string, string> {
["bleach"]
= "minicopter", ["blood"] = "scrapheli", ["ducttape"] = "rowboat", ["glue"] = "rhib", ["sticks"] = "car", ["paper"] = "crate", ["chickenspoiled"] = "solosub", ["wolfmeatspoiled"] = "duosub"
}
;
/**/
public static Dictionary<ulong, string> SkinIDToItemName = new Dictionary<ulong, string> {
[2144524645]
= "minicopter", [2144547783] = "scrapheli", [2144555007] = "rowboat", [2144558893] = "rhib", [2144560388] = "car", //[2146662467] = "horse",
[2146665840]
= "crate", [2567551241] = "solosub", [2567552797] = "duosub",
}
;
public static Dictionary<string, ulong> ItemNameToSkinID = new Dictionary<string, ulong> {
["minicopter"]
= 2144524645, ["scrapheli"] = 2144547783, ["rowboat"] = 2144555007, ["rhib"] = 2144558893, ["car"] = 2144560388, //[2146662467] = "horse",
["crate"]
= 2146665840, ["solosub"] = 2567551241, ["duosub"] = 2567552797,
}
;
public static Dictionary<string, string> ShortPrefabName = new Dictionary<string, string> {
["minicopter"]
= "assets/content/vehicles/minicopter/minicopter.entity.prefab", ["scrapheli"] = "assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab", ["rowboat"] = "assets/content/vehicles/boats/rowboat/rowboat.prefab", ["rhib"] = "assets/content/vehicles/boats/rhib/rhib.prefab", ["car"] = "assets/content/vehicles/sedan_a/sedantest.entity.prefab", //["horse"] = "assets/rust.ai/nextai/testridablehorse.prefab",
["crate"]
= "assets/prefabs/deployable/chinooklockedcrate/codelockedhackablecrate.prefab", ["parachute"] = "assets/prefabs/misc/parachute/parachute.prefab", ["2module"] = "assets/content/vehicles/modularcar/2module_car_spawned.entity.prefab", ["3module"] = "assets/content/vehicles/modularcar/3module_car_spawned.entity.prefab", ["4module"] = "assets/content/vehicles/modularcar/4module_car_spawned.entity.prefab", ["solosub"] = "assets/content/vehicles/submarine/submarinesolo.entity.prefab", ["duosub"] = "assets/content/vehicles/submarine/submarineduo.entity.prefab"
}
;
public static class SignalDefinitions {
public static Dictionary<string, SignalDefinition> definitions;
public static void GetTranslatedDefinitions() {
definitions = new Dictionary<string, SignalDefinition> {
["minicopter"]
= new SignalDefinition {
itemSuffix = MSG(MSG_DROP_NAME_MINICOPTER), skinID = 2144524645
}
, ["scrapheli"] = new SignalDefinition {
itemSuffix = MSG(MSG_DROP_NAME_SCRAPHELI), skinID = 2144547783
}
, ["rowboat"] = new SignalDefinition {
itemSuffix = MSG(MSG_DROP_NAME_ROWBOAT), skinID = 2144555007
}
, ["rhib"] = new SignalDefinition {
itemSuffix = MSG(MSG_DROP_NAME_RHIB), skinID = 2144558893
}
, ["car"] = new SignalDefinition {
itemSuffix = MSG(MSG_DROP_NAME_CAR), skinID = 2144560388
}
, //["horse"] = new SignalDefinition { itemSuffix = "Horse", skinID = 2146662467 },
["crate"]
= new SignalDefinition {
itemSuffix = MSG(MSG_DROP_NAME_CRATE), skinID = 2146665840
}
, ["solosub"] = new SignalDefinition {
itemSuffix = MSG(MSG_DROP_NAME_SOLO_SUB), skinID = 2567551241
}
, ["duosub"] = new SignalDefinition {
itemSuffix = MSG(MSG_DROP_NAME_DUO_SUB), skinID = 2567552797
}
, ["normal"] = new SignalDefinition {
itemSuffix = MSG(MSG_DROP_NAME_NORMAL), skinID = 0
}
}
;
}
}
public struct SignalDefinition {
public ulong skinID;
public string itemSuffix;
}
//lookups
//public static Dictionary<uint, CustomSignal> CustomSignals;// = new Dictionary<uint, CustomSignal>();
public static Dictionary<BaseEntity, string> CustomCargoPlanes;
// = new Dictionary<BaseEntity, string>();
public static Dictionary<uint, CustomDrop> EntityIDToCustomDrop;
// = new Dictionary<uint, CustomDrop>();
//same as above, but used for quick iterating when unloading
public static Dictionary<uint, CustomDrop> JustMainEntityIDToCustomDrop;
// = new Dictionary<uint, CustomDrop>();
public static Dictionary<uint, CustomNormalDrop> EntityIDToNormalDrop;
// = new Dictionary<uint, CustomNormalDrop>();
#endregion
#region CONFIG
private ConfigData configData;
protected override void LoadDefaultConfig() {
PrintWarning("Generating default config...");
configData = new ConfigData();
SaveConfigData();
}
private void ProcessConfigData() {
bool updateConfig = false;
string oldVersion = configData.version;
bool migrateStage1 = false;
bool migrateStage2 = false;
bool migrateStage3 = false;
bool migrateStage4 = false;
bool migrateStage5 = false;
if (configData.version == "1.0.0") {
migrateStage1 = true;
migrateStage2 = true;
}
else if (configData.version == "1.0.1") {
migrateStage2 = true;
}
else if (configData.version == "1.0.2") {
migrateStage3 = true;
}
else if (configData.version == "1.0.3") {
migrateStage4 = true;
}
else if (configData.version == "1.0.4") {
migrateStage5 = true;
}
if (migrateStage1) {
//add plane speed and plane height in 1.0.1
configData.planeSpeed = 1.0F;
configData.planeHeight = 250F;
}
if (migrateStage2) {
//add locked crate timer and option to announce drops in chat in 1.0.2
configData.crateSeconds = 900F;
configData.announceDropsInChat = true;
configData.chatIcon = 0;
configData.use3rdPartyStacking = false;
}
//migrateStage3 does nothing
if (migrateStage4) {
configData.enableFireworks = true;
configData.enableFireworksForPrivateToo = false;
configData.launchFireworkEveryXSec = 3F;
configData.maxFireworkShowDuration = 180F;
configData.maxNumberOfFireworks = 40;
configData.fireworkPrebabEnabled = new Dictionary<string, bool> {
[PREFAB_FIREWORK_BLUE]
= true, [PREFAB_FIREWORK_RED] = true, [PREFAB_FIREWORK_GREEN] = true, [PREFAB_FIREWORK_VIOLET] = true, [PREFAB_FIREWORK_ORANGE] = true, [PREFAB_FIREWORK_CHAMPAGNE] = true, [PREFAB_ROMAN_BLUE] = true, [PREFAB_ROMAN_GREEN] = true, [PREFAB_ROMAN_VIOLET] = true
}
;
}
if (migrateStage5) {
if (!configData.dropConfigs.ContainsKey("solosub")) {
configData.dropConfigs.Add("solosub", new DropConfig {
name = "solosub", applyToNatural = false, priceCurrency = 200, priceEconomics = 200, priceServerRewards = 2, randomDropWeight = 0F, randomLootWeight = 1F, comesWithFuel = 50, comesWithHealth = 1.0F, enableInVendingMachine = false, enableInCommandShop = true, currencyItemID = -932201673, vendingMachineRestockQuantity = 10, permission = null
}
);
}
if (!configData.dropConfigs.ContainsKey("duosub")) {
configData.dropConfigs.Add("duosub", new DropConfig {
name = "duosub", priceCurrency = 400, priceEconomics = 400, priceServerRewards = 4, randomDropWeight = 0F, randomLootWeight = 1F, comesWithFuel = 100, comesWithHealth = 1.0F, enableInVendingMachine = false, enableInCommandShop = true, currencyItemID = -932201673, vendingMachineRestockQuantity = 10, permission = null
}
);
}
}
updateConfig = migrateStage1 || migrateStage2 || migrateStage3 || migrateStage4 || migrateStage5 || configData.version == "1.0.5";
if (updateConfig) {
//update the version
configData.version = VERSION;
//and save config data
SaveConfigData();
Instance.PrintWarning($"Config data was migrated from {oldVersion} to {VERSION} succesfully.");
}
configData.fireworkPrefabList = configData.fireworkPrebabEnabled.Where(e => e.Value == true).ToDictionary(e => e.Key, e => e.Value).Keys.ToList();
}
private void LoadConfigData() {
PrintWarning("Loading configuration file...");
try {
configData = Config.ReadObject<ConfigData>();
}
catch {
configData = new ConfigData();
}
//SaveConfigData();
}
private void SaveConfigData() {
Config.WriteObject(configData, true);
}
public class ExtraSettingsModular {
[JsonProperty("Weighted chance that the dropped vehicle will have a 2-module chassis")]
public float randomWeight2modules;
[JsonProperty("Weighted chance that the dropped vehicle will have a 3-module chassis")]
public float randomWeight3modules;
[JsonProperty("Weighted chance that the dropped vehicle will have a 4-module chassis")]
public float randomWeight4modules;
//small engine + cockpit module
[JsonProperty("Cockpit module (small engine) comes with random parts")]
public bool moduleCockpitEngineComesWithParts;
//small engine
[JsonProperty("Cockpit module's weighted chances of dropping with this crankshaft: (crankshaft1=low, crankshaft2=medium, crankshaft3=high quality, none=no crankshaft")]
public Dictionary<string, float> moduleCockpitEngineCrankshaftChances;
[JsonProperty("Cockpit module's weighted chances of dropping with this carburetor: (carburetor1=low, carburetor2=medium, carburetor3=high quality, none=no carburetor")]
public Dictionary<string, float> moduleCockpitEngineCarburetorChances;
[JsonProperty("Cockpit module's weighted chances of dropping with these valves: (valves1=low, valves2=medium, valves3=high quality, none=no valves")]
public Dictionary<string, float> moduleCockpitEngineValvesChances;
[JsonProperty("Cockpit module's weighted chances of dropping with these sparkplugs: (sparkplugs1=low, sparkplugs2=medium, sparkplugs3=high quality, none=no sparkplugs")]
public Dictionary<string, float> moduleCockpitEngineSparkplugsChances;
[JsonProperty("Cockpit module's weighted chances of dropping with these pistons: (pistons1=low, pistons2=medium, pistons3=high quality, none=no pistons")]
public Dictionary<string, float> moduleCockpitEnginePistonsChances;
[JsonProperty("Engine module (big engine, so it has double valves, pistons and sparkplugs!) comes with random parts")]
public bool moduleBigEngineComesWithParts;
//big engine - double valves, pistons and sparkplugs
//[JsonProperty("Engine module's weighted chances of dropping with this crankshaft: (crankshaft1=low, crankshaft2=medium, crankshaft3=high quality, none=no crankshaft")]
//public Dictionary<string, float> moduleBigEngineCrankshaftChances;
//[JsonProperty("Engine module's weighted chances of dropping with this carburetor: (carburetor1=low, carburetor2=medium, carburetor3=high quality, none=no carburetor")]
//public Dictionary<string, float> moduleBigEngineCarburetorChances;
//[JsonProperty("Engine module's weighted chances of dropping with these valves A: (valves1=low, valves2=medium, valves3=high quality, none=no valves")]
//public Dictionary<string, float> moduleBigEngineValvesAChances;
[JsonProperty("Engine module's weighted chances of dropping with these valves B: (valves1=low, valves2=medium, valves3=high quality, none=no valves")]
public Dictionary<string, float> moduleBigEngineValvesBChances;
//[JsonProperty("Engine module's weighted chances of dropping with these sparkplugs A: (sparkplugs1=low, sparkplugs2=medium, sparkplugs3=high quality, none=no sparkplugs")]
//public Dictionary<string, float> moduleBigEngineSparkplugsAChances;
[JsonProperty("Engine module's weighted chances of dropping with these sparkplugs B: (sparkplugs1=low, sparkplugs2=medium, sparkplugs3=high quality, none=no sparkplugs")]
public Dictionary<string, float> moduleBigEngineSparkplugsBChances;
[JsonProperty("Engine module's weighted chances of dropping with these pistons A: (pistons1=low, pistons2=medium, pistons3=high quality, none=no pistons")]
//public Dictionary<string, float> moduleBigEnginePistonsAChances;
//[JsonProperty("Engine module's weighted chances of dropping with these pistons B: (pistons1=low, pistons2=medium, pistons3=high quality, none=no pistons")]
public Dictionary<string, float> moduleBigEnginePistonsBChances;
//needs to be recalculated when config changes/loads
[JsonIgnore]
public float randomWeightModulesSum;
[JsonIgnore]
public float randomWeightCrankshaftSum;
[JsonIgnore]
public float randomWeightCarburetorSum;
[JsonIgnore]
public float randomWeightSparkplugsASum;
[JsonIgnore]
public float randomWeightSparkplugsBSum;
[JsonIgnore]
public float randomWeightValvesASum;
[JsonIgnore]
public float randomWeightValvesBSum;
[JsonIgnore]
public float randomWeightPistonsASum;
[JsonIgnore]
public float randomWeightPistonsBSum;
}
public class DropConfig {
[JsonProperty("Price (Currency)")]
public int priceCurrency;
[JsonProperty("Price (ServerRewards)")]
public int priceServerRewards;
[JsonProperty("Price (Economics)")]
public int priceEconomics;
[JsonProperty("Currency item ID (Outpost Vending Machine), default -932201673 (scrap)")]
public int currencyItemID;
[JsonProperty("Amount of fuel it drops with (vehicles only)")]
public int comesWithFuel;
[JsonProperty("Amount of health it drops with (vehicles only, default 1.0 = full health)")]
public float comesWithHealth;
[JsonProperty("Cargo event random weight")]
public float randomDropWeight;
[JsonProperty("Loot crate random weight")]
public float randomLootWeight;
[JsonProperty("Enable selling in the dedicated vending machine")]
public bool enableInVendingMachine;
[JsonProperty("Enable selling through the /vabuy command - if disabled or price is 0, it won't shop up")]
public bool enableInCommandShop;
[JsonProperty("Amount when re-stocking the vending machine (0 disables it)")]
public int vendingMachineRestockQuantity;
[JsonProperty("Permission needed to use/purchase this kind")]
public string permission;
[JsonProperty("DROP NAME ID, LEAVE THIS ALONE OR YOU'RE GONNA HAVE BAD TIME")]
public string name;
[JsonProperty("Apply fuel/health/extra settings to vehicles spawned naturally")]
public bool applyToNatural;
[JsonProperty("!Extra settings for the drop, only applies to Modular Vehicles")]
public ExtraSettingsModular extraSettings;
}
public class ConfigData {
[JsonProperty("Use 3RD party plugin to handle stack sizes, like StacksExtended, Stack Size Controller etc")]
public bool use3rdPartyStacking = false;
[JsonProperty("!version")]
public string version = VERSION;
[JsonProperty("Can mount/loot drops when the parachute is still attached")]
public bool usableWithParachute = false;
[JsonProperty("Vehicles don't take damage when the parachute is still attached")]
public bool indestructibleWithParachute = true;
[JsonProperty("Vehicles take decay damage when the parachute is still attached")]
public bool decaysWithParachute = false;
[JsonProperty("When the drop is shot/damaged, detach the parachute")]
public bool damageDetachesParachute = false;
[JsonProperty("How far from the thrown signal a custom drop will land, 0 is precise position, 20 is Rust default")]
public float inaccuracy = 20f;
[JsonProperty("After a custom drop called with a supply signal lands, only authorised players can mount/loot it for a time period")]
public bool enablePrivateSignals = true;
[JsonProperty("Private drops are indestructible until claimed/unlocked from expiration")]
public bool privateDropsIndestructible = false;
[JsonProperty("After a custom drop called is made private, authorised players will include the caller's teammates, too")]
public bool privateSignalsIncludeTeammates = true;
[JsonProperty("How long for the unauthorised access protection to wear off (in seconds)")]
public float unlockPrivateDropAfter = 60F;
[JsonProperty("Fall speed for the drop, default 1.0 is the same speed as normal supply drops")]
public float fallSpeedWithParachute = 1.0F;
[JsonProperty("Enable a /vabuy chat command shop for players")]
public bool enableCommandShop = true;
[JsonProperty("Default method of payment for the chat command shop (Currency/ServerRewards/Economics), default Currency")]
public string defaultPayment = "Currency";
[JsonProperty("Add a vending machine that sells custom supply signals at Outpost")]
public bool enableVendingMachine = true;
[JsonProperty("Vending machine at Outpost also sells normal supply signal")]
public bool vendingMachineHasNormal = true;
[JsonProperty("Command shop accessed by /vabuy has a normal supply signal in stock")]
public bool commandShopHasNormal = true;
[JsonProperty("Price of the normal supply signal (currency, applies both to /vabuy and vending machines)")]
public int priceNormalCurrency = 400;
[JsonProperty("Price of the normal supply signal (ServerRewards)")]
public int priceNormalServerRewards = 4;
[JsonProperty("Price of the normal supply signal (Economics)")]
public int priceNormalEconomics = 400;
[JsonProperty("Permission needed to buy a normal drop (leave null to let everyone buy)")]
public string permissionNormal = null;
[JsonProperty("Currency (item ID) of the normal supply signal sold at Outpost, default -932201673 (scrap)")]
public int normalCurrencyItemID = -932201673;
[JsonProperty("Amount of the normal supply signal sold at Outpost each time the machine restocks")]
public int vendingMachineNormalQuantity = 10;
[JsonProperty("Vending machine location coordinates are relative to first Outpost found")]
public bool vendingMachineLocationIsRelative = true;
[JsonProperty("Outpost vending machine name, something like Supply Signals will do")]
public string vendingMachineCustomName = "Surprise! Supplies";
[JsonProperty("Vending machine position x")]
public float vendingMachinePosX = 31.87F;
[JsonProperty("Vending machine position y")]
public float vendingMachinePosY = 1.485F;
[JsonProperty("Vending machine position z")]
public float vendingMachinePosZ = -11.75F;
[JsonProperty("Vending machine rotation x")]
public float vendingMachineRotX = 0F;
[JsonProperty("Vending machine rotation y")]
public float vendingMachineRotY = 270F;
[JsonProperty("Vending machine rotation z")]
public float vendingMachineRotZ = 0F;
[JsonProperty("How often to re-stock the vending machine (in minutes)")]
public uint vendingMachineRestockEvery = 60;
[JsonProperty("Enable custom drops for random cargo plane events")]
public bool enableRandomDrop = true;
[JsonProperty("Enable custom supply signals spawning in loot crates")]
public bool enableRandomLoot = true;
[JsonProperty("Chance for a random carge plane drop to be custom (default 0.5 = 50%)")]
public float customDropChance = 0.5F;
[JsonProperty("Chance for a supply signal in loot crates to be custom (default 0.5 = 50%)")]
public float customLootChance = 0.5F;
[JsonProperty("Custom drop settings by their kind")]
public Dictionary<string, DropConfig> dropConfigs = new Dictionary<string, DropConfig> {
["solosub"]
= new DropConfig {
name = "solosub", applyToNatural = false, priceCurrency = 200, priceEconomics = 200, priceServerRewards = 2, randomDropWeight = 0F, randomLootWeight = 1F, comesWithFuel = 50, comesWithHealth = 1.0F, enableInVendingMachine = false, enableInCommandShop = true, currencyItemID = -932201673, vendingMachineRestockQuantity = 10, permission = null
}
, ["duosub"] = new DropConfig {
name = "duosub", priceCurrency = 400, priceEconomics = 400, priceServerRewards = 4, randomDropWeight = 0F, randomLootWeight = 1F, comesWithFuel = 100, comesWithHealth = 1.0F, enableInVendingMachine = false, enableInCommandShop = true, currencyItemID = -932201673, vendingMachineRestockQuantity = 10, permission = null
}
, ["rowboat"] = new DropConfig {
name = "rowboat", applyToNatural = false, priceCurrency = 100, priceEconomics = 100, priceServerRewards = 1, randomDropWeight = 0F, randomLootWeight = 1F, comesWithFuel = 10, comesWithHealth = 1.0F, enableInVendingMachine = true, enableInCommandShop = true, currencyItemID = -932201673, vendingMachineRestockQuantity = 10, permission = null
}
, ["rhib"] = new DropConfig {
name = "rhib", priceCurrency = 500, priceEconomics = 500, priceServerRewards = 5, randomDropWeight = 0F, randomLootWeight = 1F, comesWithFuel = 80, comesWithHealth = 1.0F, enableInVendingMachine = true, enableInCommandShop = true, currencyItemID = -932201673, vendingMachineRestockQuantity = 10, permission = null
}
, ["minicopter"] = new DropConfig {
name = "minicopter", applyToNatural = false, priceCurrency = 800, priceEconomics = 800, priceServerRewards = 8, randomDropWeight = 1F, randomLootWeight = 1F, comesWithFuel = 100, comesWithHealth = 1.0F, enableInVendingMachine = true, enableInCommandShop = true, currencyItemID = -932201673, vendingMachineRestockQuantity = 10, permission = null
}
, ["scrapheli"] = new DropConfig {
name = "scrapheli", applyToNatural = false, priceCurrency = 1200, priceEconomics = 1200, priceServerRewards = 12, randomDropWeight = 1F, randomLootWeight = 1F, comesWithFuel = 100, comesWithHealth = 1.0F, enableInVendingMachine = true, enableInCommandShop = true, currencyItemID = -932201673, vendingMachineRestockQuantity = 10, permission = null
}
, ["crate"] = new DropConfig {
name = "crate", applyToNatural = false, priceCurrency = 2000, priceEconomics = 2000, priceServerRewards = 20, randomDropWeight = 1F, randomLootWeight = 1F, comesWithFuel = 0, comesWithHealth = 1.0F, enableInVendingMachine = true, enableInCommandShop = true, currencyItemID = -932201673, vendingMachineRestockQuantity = 10, permission = null
}
, //big engines have double pistons, double spark plugs and double valves
["car"]
= new DropConfig {
name = "car", applyToNatural = true, priceCurrency = 1000, priceEconomics = 1000, priceServerRewards = 10, randomDropWeight = 1F, randomLootWeight = 1F, comesWithFuel = 40, comesWithHealth = 1.0F, enableInVendingMachine = true, enableInCommandShop = true, currencyItemID = -932201673, vendingMachineRestockQuantity = 10, permission = null, extraSettings = new ExtraSettingsModular {
randomWeight2modules = 0.33F, randomWeight3modules = 0.33F, randomWeight4modules = 0.33F, moduleCockpitEngineComesWithParts = true, moduleCockpitEngineCarburetorChances = new Dictionary<string, float> {
["none"]
= 0F, ["carburetor1"] = 0.5F, ["carburetor2"] = 0.3F, ["carburetor3"] = 0.2F
}
, moduleCockpitEngineCrankshaftChances = new Dictionary<string, float> {
["none"]
= 0F, ["crankshaft1"] = 0.5F, ["crankshaft2"] = 0.3F, ["crankshaft3"] = 0.2F
}
, moduleCockpitEnginePistonsChances = new Dictionary<string, float> {
["none"]
= 0F, ["pistons1"] = 0.5F, ["pistons2"] = 0.3F, ["pistons3"] = 0.2F
}
, moduleCockpitEngineSparkplugsChances = new Dictionary<string, float> {
["none"]
= 0F, ["sparkplugs1"] = 0.5F, ["sparkplugs2"] = 0.3F, ["sparkplugs3"] = 0.2F
}
, moduleCockpitEngineValvesChances = new Dictionary<string, float> {
["none"]
= 0F, ["valves1"] = 0.5F, ["valves2"] = 0.3F, ["valves3"] = 0.2F
}
, moduleBigEngineComesWithParts = true, moduleBigEnginePistonsBChances = new Dictionary<string, float> {
["none"]
= 0F, ["pistons1"] = 0.5F, ["pistons2"] = 0.3F, ["pistons3"] = 0.2F
}
, moduleBigEngineSparkplugsBChances = new Dictionary<string, float> {
["none"]
= 0F, ["sparkplugs1"] = 0.5F, ["sparkplugs2"] = 0.3F, ["sparkplugs3"] = 0.2F
}
, moduleBigEngineValvesBChances = new Dictionary<string, float> {
["none"]
= 0F, ["valves1"] = 0.5F, ["valves2"] = 0.3F, ["valves3"] = 0.2F
}
}
}
, //["horse"] = new DropConfig { price = 0, randomDropWeight = 0F, randomLootWeight = 0F, permission = null }
}
;
//1.0.1
//
[JsonProperty("Height of the plane, how many meters above map's highest point, 250F is default Rust height")]
public float planeHeight = 250F;
[JsonProperty("Speed of the plane, 1.0 is the default Rust speed, 2.0 is twice as fast, etc (0.01F to positive infinity)")]
public float planeSpeed = 1.0F;
//1.0.2
[JsonProperty("How long for a locked crate to unlock, in whole seconds (900 is Rust default)")]
public float crateSeconds = 900F;
[JsonProperty("Announce random cargo plane events and called custom supply signals in chat?")]
public bool announceDropsInChat = true;
[JsonProperty("Icon ID for the chat (long steam user ID, starting with 7)")]
public ulong chatIcon = 0;
//1.0.4
[JsonProperty("Enable periodical fireworks after the drop has landed to indicate the drop location?")]
public bool enableFireworks = true;
[JsonProperty("Fireworks are enabled for private drops, too?")]
public bool enableFireworksForPrivateToo = false;
[JsonProperty("When fireworks are enabled, launch a new firework every X amount of seconds")]
public float launchFireworkEveryXSec = 3F;
[JsonProperty("Stop launching fireworks after this amount of seconds")]
public float maxFireworkShowDuration = 180F;
[JsonProperty("Stop launching fireworks after launching this number of them")]
public int maxNumberOfFireworks = 40;
[JsonProperty("Enable Notify plugin capabilities (messages printed in the chat will also be sent there)")]
public bool enableNotifyPlugin = true;
[JsonProperty("Choose from the following list of firework prefabs at random, set to false to disable certain kinds")]
public Dictionary<string, bool> fireworkPrebabEnabled = new Dictionary<string, bool> {
[PREFAB_FIREWORK_BLUE]
= true, [PREFAB_FIREWORK_RED] = true, [PREFAB_FIREWORK_GREEN] = true, [PREFAB_FIREWORK_VIOLET] = true, [PREFAB_FIREWORK_ORANGE] = true, [PREFAB_FIREWORK_CHAMPAGNE] = true, [PREFAB_ROMAN_BLUE] = true, [PREFAB_ROMAN_GREEN] = true, [PREFAB_ROMAN_VIOLET] = true
}
;
[JsonIgnore]
//this needs to be re-calculated after loading config
public List<string> fireworkPrefabList = null;
//these needs re-calculated when something about them changes
[JsonIgnore]
public float weightSumDrop;
[JsonIgnore]
public float weightSumLoot;
[JsonIgnore]
public Vector3 vendingMachinePos;
[JsonIgnore]
public Vector3 vendingMachineRot;
[JsonIgnore]
public VendingMachine dedicatedVendingMachine = null;
[JsonIgnore]
public DroppedItem dedicatedVendingMachineDummy = null;
}
#endregion
#region MONO
//attach to a new gameobject after landing
public class FireworkLauncher : MonoBehaviour {
public int launchedSoFar = 0;
public float stopLaunchingAt = UnityEngine.Time.realtimeSinceStartup + Instance.configData.maxFireworkShowDuration;
public float updateRate = Instance.configData.launchFireworkEveryXSec;
public float lastUpdate = UnityEngine.Time.realtimeSinceStartup;
private void FixedUpdate() {
if (UnityEngine.Time.realtimeSinceStartup <= lastUpdate + updateRate) {
return;
}
lastUpdate = UnityEngine.Time.realtimeSinceStartup;
if (UnityEngine.Time.realtimeSinceStartup > stopLaunchingAt) {
DestroyImmediate(gameObject);
return;
}
//launch firework
var randomPrefab = RandomFireworkPrefab();
if (randomPrefab != null) {
RaycastHit rayHit;
var cast = Physics.Raycast(new Vector3(transform.position.x, transform.position.y + 200, transform.position.z), Vector3.down, out rayHit, 300F, int.MaxValue);
if (cast) {
var firework = GameManager.server.CreateEntity(randomPrefab, rayHit.point + Vector3.up * 2F) as RepeatingFirework;
firework.transform.up = Vector3.up;
firework.Spawn();
firework.enableSaving = false;
firework.ClientRPC(null, "RPCFire");
firework.Kill();
}
}
launchedSoFar++;
if (launchedSoFar >= Instance.configData.maxNumberOfFireworks) {
DestroyImmediate(gameObject);
}
}
}
public class CustomPlane : MonoBehaviour {
public string kind;
public ulong ownerID;
public CargoPlane plane;
void Awake() {
plane = gameObject.GetComponent<CargoPlane>();
ReplacementUpdateDropPosition();
}
public void ReplacementUpdateDropPosition() {
var newDropPosition = plane.dropPosition;
float x = TerrainMeta.Size.x;
float num = Terrain
// ... [Code preview truncated due to length. Full source in attached file] ...