C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
// #define DEBUG
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using Facepunch;
using Network;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust;
using Rust;
using Rust.Modular;
using UnityEngine;
using Debug = UnityEngine.Debug;
using Random = UnityEngine.Random;
// TODO: Fix mincopters spawning above user.namespace Oxide.Plugins
{
[Info("Vehicle Licence", "Sorrow/TheDoc/Arainrr", "1.8.8")]
[Description("Allows players to buy vehicles and then spawn or store it")]
public class VehicleLicence : RustPlugin {
#region Fields
[PluginReference]
private readonly Plugin Economics, ServerRewards, Friends, Clans, NoEscape, LandOnCargoShip, RustTranslationAPI, ZoneManager;
private readonly string PERMISSION_USE = "vehiclelicence.use";
private readonly string PERMISSION_ALL = "vehiclelicence.all";
private readonly string PERMISSION_ADMIN = "vehiclelicence.admin";
private readonly string PERMISSION_BYPASS_COST = "vehiclelicence.bypasscost";
private readonly string PERMISSION_NO_DAMAGE = "vehiclelicence.nodamage";
private readonly string PERMISSION_NO_COLLISION_DAMAGE = "vehiclelicence.nocollisiondamage";
private const int ITEMID_FUEL = -946369541;
private const int ITEMID_HOTAIRBALLOON_ARMOR = -1989600732;
private const string PREFAB_ITEM_DROP = "assets/prefabs/misc/item drop/item_drop.prefab";
//BIKES
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_MOTORBIKE = "assets/content/vehicles/bikes/motorbike.prefab";
private const string PREFAB_MOTORBIKE_SIDECAR = "assets/content/vehicles/bikes/motorbike_sidecar.prefab";
//SPECIAL
private const string PREFAB_ATV = "assets/custom/atv.prefab";
private const string PREFAB_SOFA = "assets/custom/racesofa.prefab";
private const string PREFAB_WATERBIRD = "assets/custom/waterheli.prefab";
private const string PREFAB_WARBIRD = "assets/custom/warbird.prefab";
private const string PREFAB_LITTLEBIRD = "assets/custom/littlebird.prefab";
private const string PREFAB_FIGHTER = "assets/custom/fighter.prefab";
private const string PREFAB_OLDFIGHTER = "assets/custom/oldfighter.prefab";
private const string PREFAB_FIGHTERBUS = "assets/custom/fighterbus.prefab";
private const string PREFAB_WARBUS = "assets/custom/warbus.prefab";
private const string PREFAB_AIRBUS = "assets/custom/airbus.prefab";
private const string PREFAB_PATROLHELI = "assets/custom/patrolheli.prefab";
private const string PREFAB_RUSTWING = "assets/custom/rustwing.prefab";
private const string PREFAB_RUSTWINGDETAILED = "assets/custom/rustwing_detailed.prefab";
private const string PREFAB_RUSTWINGDETAILEDOLD = "assets/custom/rustwing_detailed_old.prefab";
private const string PREFAB_TINFIGHTER = "assets/custom/tinfighter.prefab";
private const string PREFAB_TINFIGHTERDETAILED = "assets/custom/tinfighter_detailed.prefab";
private const string PREFAB_TINFIGHTERDETAILEDOLD = "assets/custom/tinfighter_detailed_old.prefab";
private const string PREFAB_MARSFIGHTER = "assets/custom/marsfighter.prefab";
private const string PREFAB_MARSFIGHTERDETAILED = "assets/custom/marsfighter_detailed.prefab";
private const string PREFAB_SKYPLANE = "assets/custom/skyplane.prefab";
private const string PREFAB_SKYBOAT = "assets/custom/skyboat.prefab";
private const string PREFAB_TWISTEDTRUCK = "assets/custom/twistedtruck.prefab";
private const string PREFAB_TRIANWRECK = "assets/custom/trainwreck.prefab";
private const string PREFAB_TRIANWRECKER = "assets/custom/trainwrecker.prefab";
private const string PREFAB_SANTA = "assets/custom/santa.prefab";
private const string PREFAB_WARSANTA = "assets/custom/warsanta.prefab";
private const string PREFAB_WITCH = "assets/custom/witch.prefab";
private const string PREFAB_MAGICCARPET = "assets/custom/magiccarpet.prefab";
private const string PREFAB_AH69T = "assets/custom/ah69t.prefab";
private const string PREFAB_AH69R = "assets/custom/ah69r.prefab";
private const string PREFAB_AH69A = "assets/custom/ah69a.prefab";
private const string PREFAB_MAVIK = "assets/custom/mavik.prefab";
private const string PREFAB_HEAVYFIGHTER = "assets/custom/heavyfighter.prefab";
private const string PREFAB_PORCELAINCOMMANDER = "assets/custom/porcelaincommander.prefab";
private const string PREFAB_DUNEBUGGIE = "assets/custom/dunebuggie.prefab";
private const string PREFAB_DUNETRUCKARMED = "assets/custom/dunetruckarmed.prefab";
private const string PREFAB_DUNETRUCKUNARMED = "assets/custom/dunetruckunarmed.prefab";
private const string PREFAB_DOOMSDAYDISCOVAN = "assets/custom/doomsdaydiscovan.prefab";
private const string PREFAB_FORKLIFT = "assets/custom/forklift.prefab";
private const string PREFAB_LAWNMOWER = "assets/custom/lawnmower.prefab";
private const string PREFAB_CHARIOT = "assets/custom/chariot.prefab";
private const string PREFAB_SOULHARVESTER = "assets/custom/soulharvester.prefab";
//OTHER
private const string PREFAB_KAYAK = "assets/content/vehicles/boats/kayak/kayak.prefab";
private const string PREFAB_TUGBOAT = "assets/content/vehicles/boats/tugboat/tugboat.prefab";
private const string PREFAB_ROWBOAT = "assets/content/vehicles/boats/rowboat/rowboat.prefab";
private const string PREFAB_RHIB = "assets/content/vehicles/boats/rhib/rhib.prefab";
private const string PREFAB_SEDAN = "assets/content/vehicles/sedan_a/sedantest.entity.prefab";
private const string PREFAB_HOTAIRBALLOON = "assets/prefabs/deployable/hot air balloon/hotairballoon.prefab";
private const string PREFAB_MINICOPTER = "assets/content/vehicles/minicopter/minicopter.entity.prefab";
private const string PREFAB_ATTACKHELICOPTER = "assets/content/vehicles/attackhelicopter/attackhelicopter.entity.prefab";
private const string PREFAB_TRANSPORTCOPTER = "assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab";
private const string PREFAB_CHINOOK = "assets/prefabs/npc/ch47/ch47.entity.prefab";
private const string PREFAB_RIDABLEHORSE = "assets/content/vehicles/horse/ridablehorse.prefab";
private const string PREFAB_WORKCART = "assets/content/vehicles/trains/workcart/workcart.entity.prefab";
private const string PREFAB_SEDANRAIL = "assets/content/vehicles/sedan_a/sedanrail.entity.prefab";
private const string PREFAB_MAGNET_CRANE = "assets/content/vehicles/crane_magnet/magnetcrane.entity.prefab";
private const string PREFAB_SUBMARINE_DUO = "assets/content/vehicles/submarine/submarineduo.entity.prefab";
private const string PREFAB_SUBMARINE_SOLO = "assets/content/vehicles/submarine/submarinesolo.entity.prefab";
private const string PREFAB_CHASSIS_SMALL = "assets/content/vehicles/modularcar/car_chassis_2module.entity.prefab";
private const string PREFAB_CHASSIS_MEDIUM = "assets/content/vehicles/modularcar/car_chassis_3module.entity.prefab";
private const string PREFAB_CHASSIS_LARGE = "assets/content/vehicles/modularcar/car_chassis_4module.entity.prefab";
private const string PREFAB_SNOWMOBILE = "assets/content/vehicles/snowmobiles/snowmobile.prefab";
private const string PREFAB_SNOWMOBILE_TOMAHA = "assets/content/vehicles/snowmobiles/tomahasnowmobile.prefab";
// Train Engine
private const string PREFAB_TRAINENGINE = "assets/content/vehicles/trains/workcart/workcart_aboveground.entity.prefab";
private const string PREFAB_TRAINENGINE_COVERED = "assets/content/vehicles/trains/workcart/workcart_aboveground2.entity.prefab";
private const string PREFAB_TRAINENGINE_LOCOMOTIVE = "assets/content/vehicles/trains/locomotive/locomotive.entity.prefab";
// Train Car
private const string PREFAB_TRAINWAGON_A = "assets/content/vehicles/trains/wagons/trainwagona.entity.prefab";
private const string PREFAB_TRAINWAGON_B = "assets/content/vehicles/trains/wagons/trainwagonb.entity.prefab";
private const string PREFAB_TRAINWAGON_C = "assets/content/vehicles/trains/wagons/trainwagonc.entity.prefab";
private const string PREFAB_TRAINWAGON_UNLOADABLE = "assets/content/vehicles/trains/wagons/trainwagonunloadable.entity.prefab";
private const string PREFAB_TRAINWAGON_UNLOADABLE_FUEL = "assets/content/vehicles/trains/wagons/trainwagonunloadablefuel.entity.prefab";
private const string PREFAB_TRAINWAGON_UNLOADABLE_LOOT = "assets/content/vehicles/trains/wagons/trainwagonunloadableloot.entity.prefab";
private const string PREFAB_CABOOSE = "assets/content/vehicles/trains/caboose/traincaboose.entity.prefab";
// Defaults for Vehicle Modifications
private readonly float TUGBOAT_ENGINETHRUST = 200000f;
private readonly float HELICOPTER_LIFT = 0.25f;
private readonly Vector3 SCRAP_HELICOPTER_TORQUE = new Vector3(8000.0f, 8000.0f, 4000.0f);
private readonly Vector3 MINICOPTER_TORQUE = new Vector3(400.0f, 400.0f, 200.0f);
private readonly Vector3 ATTACK_HELICOPTER_TORQUE = new Vector3(8000.0f, 8000.0f, 5200.0f);
private const int LAYER_GROUND = Layers.Solid | Layers.Mask.Water;
private readonly object _false = false;
private bool finishedLoading = false;
public static VehicleLicence Instance {
get;
private set;
}
public readonly Dictionary<BaseEntity, Vehicle> vehiclesCache = new Dictionary<BaseEntity, Vehicle>();
public readonly Dictionary<string, BaseVehicleSettings> allVehicleSettings = new Dictionary<string, BaseVehicleSettings>();
public readonly Dictionary<string, string> commandToVehicleType = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
public enum NormalVehicleType {
Tugboat, Rowboat, RHIB, Sedan, HotAirBalloon, ArmoredHotAirBalloon, MiniCopter, AttackHelicopter, TransportHelicopter, Chinook, RidableHorse, WorkCart, SedanRail, MagnetCrane, SubmarineSolo, SubmarineDuo, Snowmobile, TomahaSnowmobile, Kayak, PedalBike, PedalTrike, MotorBike, MotorBike_SideCar,
}
public enum CustomVehicleType {
ATV, RaceSofa, WaterBird, WarBird, LittleBird, Fighter, OldFighter, FighterBus, WarBus, AirBus, PatrolHeli, RustWing, RustWingDetailed, RustWingDetailedOld, TinFighter, TinFighterDetailed, TinFighterDetailedOld, MarsFighter, MarsFighterDetailed, SkyPlane, SkyBoat, TwistedTruck, TrainWreck, TrainWrecker, Santa, WarSanta, Witch, MagicCarpet, Ah69t, Ah69r, Ah69a, Mavik, HeavyFighter, PorcelainCommander, DuneBuggie, DuneTruckArmed, DuneTruckUnArmed, DoomsDayDiscoVan, ForkLift, LawnMower, Chariot, SoulHarvester
}
[JsonConverter(typeof(StringEnumConverter))]
public enum ChassisType {
Small, Medium, Large
}
[JsonConverter(typeof(StringEnumConverter))]
public enum TrainComponentType {
Engine, CoveredEngine, Locomotive, WagonA, WagonB, WagonC, Unloadable, UnloadableLoot, UnloadableFuel, Caboose,
}
#endregion Fields
#region Oxide Hooks
private void Init() {
LoadData();
Instance = this;
permission.RegisterPermission(PERMISSION_USE, this);
permission.RegisterPermission(PERMISSION_ALL, this);
permission.RegisterPermission(PERMISSION_ADMIN, this);
permission.RegisterPermission(PERMISSION_BYPASS_COST, this);
permission.RegisterPermission(PERMISSION_NO_DAMAGE, this);
permission.RegisterPermission(PERMISSION_NO_COLLISION_DAMAGE, this);
bool useCustomVehicles = configData.global.useCustomVehicles;
if(useCustomVehicles && configData.customVehicles == null) {
configData.customVehicles = new CustomVehicleSettings();
SaveConfig();
}
if(useCustomVehicles) {
foreach (NormalVehicleType value in Enum.GetValues(typeof(NormalVehicleType))) {
allVehicleSettings.Add(value.ToString(), GetBaseVehicleSettings(value));
}
foreach (CustomVehicleType value in Enum.GetValues(typeof(CustomVehicleType))) {
allVehicleSettings.Add(value.ToString(), GetCustomVehicleSettings(value));
}
}
else {
foreach (NormalVehicleType value in Enum.GetValues(typeof(NormalVehicleType))) {
allVehicleSettings.Add(value.ToString(), GetBaseVehicleSettings(value));
}
}
foreach (var entry in configData.modularVehicles) {
allVehicleSettings.Add(entry.Key, entry.Value);
}
foreach (var entry in configData.trainVehicles) {
allVehicleSettings.Add(entry.Key, entry.Value);
}
foreach (var entry in allVehicleSettings) {
BaseVehicleSettings settings = entry.Value;
if (settings.UsePermission && !string.IsNullOrEmpty(settings.Permission)) {
if (!permission.PermissionExists(settings.Permission, this)) {
permission.RegisterPermission(settings.Permission, this);
}
}
if (settings.UsePermission && !string.IsNullOrEmpty(settings.BypassCostPermission)) {
if (!permission.PermissionExists(settings.BypassCostPermission, this)) {
permission.RegisterPermission(settings.BypassCostPermission, this);
}
}
foreach (var perm in settings.CooldownPermissions.Keys) {
if (!permission.PermissionExists(perm, this)) {
permission.RegisterPermission(perm, this);
}
}
foreach (var command in settings.Commands) {
if (string.IsNullOrEmpty(command)) {
continue;
}
if (!commandToVehicleType.ContainsKey(command)) {
commandToVehicleType.Add(command, entry.Key);
}
else {
PrintError($"You have the same two commands({command}).");
}
if (configData.chat.useUniversalCommand) {
cmd.AddChatCommand(command, this, nameof(CmdUniversal));
}
if (!string.IsNullOrEmpty(configData.chat.customKillCommandPrefix)) {
cmd.AddChatCommand(configData.chat.customKillCommandPrefix + command, this, nameof(CmdCustomKill));
}
}
}
cmd.AddChatCommand(configData.chat.helpCommand, this, nameof(CmdLicenseHelp));
cmd.AddChatCommand(configData.chat.buyCommand, this, nameof(CmdBuyVehicle));
cmd.AddChatCommand(configData.chat.spawnCommand, this, nameof(CmdSpawnVehicle));
cmd.AddChatCommand(configData.chat.recallCommand, this, nameof(CmdRecallVehicle));
cmd.AddChatCommand(configData.chat.killCommand, this, nameof(CmdKillVehicle));
Unsubscribe(nameof(CanMountEntity));
Unsubscribe(nameof(OnEntityTakeDamage));
Unsubscribe(nameof(OnEntityDismounted));
Unsubscribe(nameof(OnEntityEnter));
Unsubscribe(nameof(CanLootEntity));
Unsubscribe(nameof(OnEntitySpawned));
Unsubscribe(nameof(OnRidableAnimalClaimed));
Unsubscribe(nameof(OnEngineStarted));
Unsubscribe(nameof(OnVehiclePush));
}
private void OnServerInitialized() {
ServerMgr.Instance.StartCoroutine(UpdatePlayerData(TimeEx.currentTimestamp));
if (configData.global.preventMounting) {
Subscribe(nameof(CanMountEntity));
}
if (configData.global.noDecay) {
Subscribe(nameof(OnEntityTakeDamage));
}
if (configData.global.preventDamagePlayer || configData.global.safeTrainDismount || configData.global.preventDamageNPCs) {
Subscribe(nameof(OnEntityEnter));
}
if (configData.global.preventLooting) {
Subscribe(nameof(CanLootEntity));
}
if (configData.global.autoClaimFromVendor) {
Subscribe(nameof(OnEntitySpawned));
Subscribe(nameof(OnRidableAnimalClaimed));
}
if (configData.global.checkVehiclesInterval > 0 && allVehicleSettings.Any(x => x.Value.WipeTime > 0)) {
Subscribe(nameof(OnEntityDismounted));
timer.Every(configData.global.checkVehiclesInterval, CheckVehicles);
}
else if (configData.normalVehicles.miniCopter.flyHackPause > 0 || configData.normalVehicles.transportHelicopter.flyHackPause > 0 || configData.normalVehicles.attackHelicopter.flyHackPause > 0) {
Subscribe(nameof(OnEntityDismounted));
}
if (configData.normalVehicles.miniCopter.instantTakeoff || configData.normalVehicles.attackHelicopter.instantTakeoff || configData.normalVehicles.transportHelicopter.instantTakeoff) {
Subscribe(nameof(OnEngineStarted));
}
if (configData.global.preventPushing) {
Subscribe(nameof(OnVehiclePush));
}
}
private void Unload() {
if (!configData.global.storeVehicle) {
foreach (var entry in vehiclesCache) {
if (entry.Key != null && !entry.Key.IsDestroyed) {
RefundVehicleItems(entry.Value, isUnload : true);
entry.Key.Kill(BaseNetworkable.DestroyMode.Gib);
}
entry.Value.EntityId = 0;
}
}
SaveData();
Instance = null;
}
private void OnServerSave() {
timer.Once(Random.Range(0f, 60f), SaveData);
}
private void OnEntityDismounted(BaseMountable entity, BasePlayer player) {
if (entity == null) {
return;
}
if (player != null) {
BaseEntity vehicleEntity = entity.GetParentEntity();
if (configData.normalVehicles.miniCopter.flyHackPause > 0 && vehicleEntity is Minicopter) {
player.PauseFlyHackDetection(configData.normalVehicles.miniCopter.flyHackPause);
}
else if (configData.normalVehicles.transportHelicopter.flyHackPause > 0 && vehicleEntity is ScrapTransportHelicopter) {
player.PauseFlyHackDetection(configData.normalVehicles.transportHelicopter.flyHackPause);
}
else if (configData.normalVehicles.attackHelicopter.flyHackPause > 0 && vehicleEntity is AttackHelicopter) {
player.PauseFlyHackDetection(configData.normalVehicles.attackHelicopter.flyHackPause);
}
}
var vehicleParent = entity.VehicleParent();
if (vehicleParent == null || vehicleParent.IsDestroyed) {
return;
}
Vehicle vehicle;
if (!vehiclesCache.TryGetValue(vehicleParent, out vehicle)) {
return;
}
vehicle.OnDismount();
}
// TODO: Fix/finish
private void OnEngineStarted(BaseMountable entity, BasePlayer player) {
if (player == null || entity == null) return;
if (!permission.UserHasPermission(player.UserIDString, PERMISSION_USE)) return;
BaseVehicle mounted = player.GetMountedVehicle();
// Only allows vehicles spawned with the plugin to use instant take off.if (mounted == null || !vehiclesCache.ContainsKey(mounted)) return;
PlayerHelicopter heli = mounted as PlayerHelicopter;
NextTick(() => {
if (heli == null) return;
if (configData.normalVehicles.miniCopter.instantTakeoff && heli is Minicopter) {
heli.engineController.FinishStartingEngine();
return;
}
if (configData.normalVehicles.attackHelicopter.instantTakeoff && heli is AttackHelicopter) {
heli.engineController.FinishStartingEngine();
}
if (configData.normalVehicles.transportHelicopter.instantTakeoff && heli is ScrapTransportHelicopter) {
heli.engineController.FinishStartingEngine();
}
}
);
}
private object OnVehiclePush(BaseVehicle vehicle, BasePlayer player) {
if (vehicle == null || player == null) return null;
if (!vehiclesCache.TryGetValue(vehicle, out Vehicle foundVehicle)) return null;
// ulong userID = player.userID.Get();
//
// if (foundVehicle.PlayerId == userID || AreFriends(foundVehicle.PlayerId, player.userID)) return null;
// if (HasAdminPermission(player)) return null;
// Respond here
SendCantPushMessage(player, foundVehicle);
return true;
}
#region Mount
private object CanMountEntity(BasePlayer friend, BaseMountable entity) {
if (friend == null || entity == null) {
return null;
}
var vehicleParent = entity.VehicleParent();
if (vehicleParent == null || vehicleParent.IsDestroyed) {
return null;
}
Vehicle vehicle;
if (!vehiclesCache.TryGetValue(vehicleParent, out vehicle)) {
return null;
}
if (AreFriends(vehicle.PlayerId, friend.userID)) {
return null;
}
if (configData.global.preventDriverSeat && vehicleParent.HasMountPoints()) {
foreach (var mountPointInfo in vehicleParent.allMountPoints) {
if (mountPointInfo == null || mountPointInfo.mountable != entity) continue;
if (!mountPointInfo.isDriver) {
return null;
}
break;
}
}
if (HasAdminPermission(friend)) {
return null;
}
SendCantUseMessage(friend, vehicle);
return _false;
}
#endregion Mount
#region Loot
private object CanLootEntity(BasePlayer friend, RidableHorse horse) {
if (friend == null || horse == null) {
return null;
}
return CanLootEntityInternal(friend, horse);
}
private object CanLootEntity(BasePlayer friend, StorageContainer container) {
if (friend == null || container == null) return null;
var parentEntity = container.GetParentEntity();
if (parentEntity == null) return null;
return CanLootEntityInternal(friend, parentEntity);
}
private object CanLootEntityInternal(BasePlayer friend, BaseEntity parentEntity) {
Vehicle vehicle;
if (!TryGetVehicle(parentEntity, out vehicle)) {
return null;
}
if (AreFriends(vehicle.PlayerId, friend.userID)) return null;
if (HasAdminPermission(friend)) return null;
SendCantUseMessage(friend, vehicle);
return _false;
}
#endregion Loot
#region Decay
private void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitInfo) {
if (entity == null || hitInfo?.damageTypes == null) {
return;
}
Vehicle vehicle;
if (!TryGetVehicle(entity, out vehicle)) {
return;
}
if (permission.UserHasPermission(vehicle.PlayerId.ToString(), PERMISSION_NO_DAMAGE) && GetBaseVehicleDamage(vehicle.VehicleType)) {
hitInfo.damageTypes.ScaleAll(0);
return;
}
if (hitInfo.damageTypes.Has(DamageType.Collision) && permission.UserHasPermission(vehicle.PlayerId.ToString(), PERMISSION_NO_COLLISION_DAMAGE) && GetBaseVehicleCollisionDamage(vehicle.VehicleType)) {
hitInfo.damageTypes.Scale(DamageType.Collision, 0);
return;
}
if (!hitInfo.damageTypes.Has(DamageType.Decay)) return;
hitInfo.damageTypes.Scale(DamageType.Decay, 0);
}
#endregion Decay
#region Claim
private void OnEntitySpawned(Tugboat tugboat) {
TryClaimVehicle(tugboat);
}
private void OnEntitySpawned(BaseSubmarine baseSubmarine) {
TryClaimVehicle(baseSubmarine);
}
private void OnEntitySpawned(MotorRowboat motorRowboat) {
TryClaimVehicle(motorRowboat);
}
private void OnEntitySpawned(Minicopter miniCopter) {
TryClaimVehicle(miniCopter);
}
private void OnEntitySpawned(AttackHelicopter attackHelicopter) {
TryClaimVehicle(attackHelicopter);
}
private void OnRidableAnimalClaimed(RidableHorse ridableAnimal, BasePlayer player) {
TryClaimVehicle(ridableAnimal, player);
}
#endregion Claim
#region Damage
// ScrapTransportHelicopter / ModularCar / TrainEngine / MagnetCrane
private object OnEntityEnter(TriggerHurtNotChild triggerHurtNotChild, BasePlayer player) {
if (triggerHurtNotChild == null || player == null || triggerHurtNotChild.SourceEntity == null) {
return null;
}
var sourceEntity = triggerHurtNotChild.SourceEntity;
if (!vehiclesCache.ContainsKey(sourceEntity) || (!configData.global.preventDamageNPCs && !player.userID.IsSteamId())) return null;
var baseVehicle = sourceEntity as BaseVehicle;
if ((baseVehicle == null || player.userID.IsSteamId()) && configData.global.preventDamagePlayer) return _false;
if (configData.global.preventDamageNPCs && !player.userID.IsSteamId()) return _false;
if (baseVehicle is TrainEngine) {
if (!configData.global.safeTrainDismount && configData.global.preventDamagePlayer && player.userID.IsSteamId()) return _false;
if (!configData.global.safeTrainDismount) return null;
var transform = triggerHurtNotChild.transform;
MoveToPosition(player, transform.position + (Random.value >= 0.5f ? -transform.right : transform.right) * 2.5f);
return configData.global.preventDamagePlayer ? _false : null;
}
if (!configData.global.preventDamagePlayer) return null;
Vector3 pos;
if (GetDismountPosition(baseVehicle, player, out pos)) {
MoveToPosition(player, pos);
}
//triggerHurtNotChild.enabled = false;
return _false;
}
// HotAirBalloon
private object OnEntityEnter(TriggerHurt triggerHurt, BasePlayer player) {
if (triggerHurt == null || player == null) {
return null;
}
var sourceEntity = triggerHurt.gameObject.ToBaseEntity();
if (sourceEntity == null || !vehiclesCache.ContainsKey(sourceEntity)) return null;
if (configData.global.preventDamagePlayer && player.userID.IsSteamId() || (configData.global.preventDamageNPCs && !player.userID.IsSteamId())) {
MoveToPosition(player, sourceEntity.CenterPoint() + Vector3.down);
//triggerHurt.enabled = false;
return _false;
}
return null;
}
#endregion Damage
#region Destroy
private void OnEntityDeath(BaseCombatEntity entity, HitInfo info) {
OnEntityDeathOrKill(entity, true);
}
private void OnEntityKill(BaseCombatEntity entity) {
OnEntityDeathOrKill(entity);
}
#endregion Destroy
#region Reskin
private object OnEntityReskin(BaseEntity entity, ItemSkinDirectory.Skin skin, BasePlayer player) {
if (entity == null || player == null) {
return null;
}
Vehicle vehicle;
if (TryGetVehicle(entity, out vehicle)) {
return _false;
}
return null;
}
#endregion Reskin
#endregion Oxide Hooks
#region Methods
#region Message
private void SendCantUseMessage(BasePlayer friend, Vehicle vehicle) {
var settings = GetBaseVehicleSettings(vehicle.VehicleType);
if (settings != null) {
var player = RustCore.FindPlayerById(vehicle.PlayerId);
var playerName = player?.displayName ?? ServerMgr.Instance.persistance.GetPlayerName(vehicle.PlayerId) ?? "Unknown";
Print(friend, Lang("CantUse", friend.UserIDString, settings.DisplayName, $"<color=#{(player != null && player.IsConnected ? "69D214" : "FF6347")}>{playerName}</color>"));
}
}
private void SendCantPushMessage(BasePlayer friend, Vehicle vehicle) {
var settings = GetBaseVehicleSettings(vehicle.VehicleType);
if (settings == null) return;
var player = RustCore.FindPlayerById(vehicle.PlayerId);
var playerName = player?.displayName ?? ServerMgr.Instance.persistance.GetPlayerName(vehicle.PlayerId) ?? "Unknown";
Print(friend, Lang("CantPush", friend.UserIDString, settings.DisplayName, $"<color=#{(player != null && player.IsConnected ? "69D214" : "FF6347")}>{playerName}</color>"));
}
#endregion Message
#region CheckEntity
private void OnEntityDeathOrKill(BaseCombatEntity entity, bool isCrash = false) {
if (entity == null) {
return;
}
Vehicle vehicle;
if (!vehiclesCache.TryGetValue(entity, out vehicle)) {
return;
}
RefundVehicleItems(vehicle, isCrash);
var settings = GetBaseVehicleSettings(vehicle.VehicleType);
if (isCrash && settings.RemoveLicenseOnceCrash) {
RemoveVehicleLicense(vehicle.PlayerId, vehicle.VehicleType);
}
vehicle.OnDeath();
vehiclesCache.Remove(entity);
}
#endregion CheckEntity
#region CheckVehicles
private void CheckVehicles() {
var currentTimestamp = TimeEx.currentTimestamp;
foreach (var entry in vehiclesCache.ToArray()) {
if (entry.Key == null || entry.Key.IsDestroyed) {
continue;
}
if (VehicleIsActive(entry.Key, entry.Value, currentTimestamp)) {
continue;
}
if (VehicleAnyMounted(entry.Key)) {
continue;
}
entry.Key.Kill(BaseNetworkable.DestroyMode.Gib);
}
}
private bool VehicleIsActive(BaseEntity entity, Vehicle vehicle, double currentTimestamp) {
var settings = GetBaseVehicleSettings(vehicle.VehicleType);
if (settings.WipeTime <= 0) {
return true;
}
if (settings.ExcludeCupboard && entity.GetBuildingPrivilege() != null) {
return true;
}
return currentTimestamp - vehicle.LastDismount < settings.WipeTime;
}
#endregion CheckVehicles
#region Refund
private void RefundVehicleItems(Vehicle vehicle, bool isCrash = false, bool isUnload = false) {
var entity = vehicle.Entity;
if (entity == null || entity.IsDestroyed) {
return;
}
var settings = GetBaseVehicleSettings(vehicle.VehicleType);
settings.RefundVehicleItems(vehicle, isCrash, isUnload);
}
private static void DropItemContainer(BaseEntity entity, ulong playerId, List<Item> collect) {
var droppedItemContainer = GameManager.server.CreateEntity(PREFAB_ITEM_DROP, entity.GetDropPosition(), entity.transform.rotation) as DroppedItemContainer;
if (droppedItemContainer != null) {
droppedItemContainer.inventory = new ItemContainer();
droppedItemContainer.inventory.ServerInitialize(null, Mathf.Min(collect.Count, droppedItemContainer.maxItemCount));
droppedItemContainer.inventory.GiveUID();
droppedItemContainer.inventory.entityOwner = droppedItemContainer;
droppedItemContainer.inventory.SetFlag(ItemContainer.Flag.NoItemInput, true);
for (var i = collect.Count - 1; i >= 0; i--) {
var item = collect[i];
if (!item.MoveToContainer(droppedItemContainer.inventory)) {
item.DropAndTossUpwards(droppedItemContainer.transform.position);
}
}
droppedItemContainer.OwnerID = playerId;
droppedItemContainer.Spawn();
}
}
#endregion Refund
#region TryPay
private bool TryPay(BasePlayer player, BaseVehicleSettings settings, Dictionary<string, PriceInfo> prices, out string resources) {
if (permission.UserHasPermission(player.UserIDString, PERMISSION_BYPASS_COST) || permission.UserHasPermission(player.UserIDString, settings.BypassCostPermission)) {
resources = null;
return true;
}
if (!CanPay(player, prices, out resources)) {
return false;
}
var collect = Pool.Get<List<Item>>();
foreach (var entry in prices) {
if (entry.Value.amount <= 0) {
continue;
}
var itemDefinition = ItemManager.FindItemDefinition(entry.Key);
if (itemDefinition != null) {
player.inventory.Take(collect, itemDefinition.itemid, entry.Value.amount);
player.Command("note.inv", itemDefinition.itemid, -entry.Value.amount);
continue;
}
switch (entry.Key.ToLower()) {
case "economics" : Economics?.Call("Withdraw", player.userID.Get(), (double)entry.Value.amount);
continue;
case "serverrewards" : ServerRewards?.Call("TakePoints", player.userID.Get(), entry.Value.amount);
continue;
}
}
foreach (var item in collect) {
item.Remove();
}
Pool.FreeUnmanaged(ref collect);
resources = null;
return true;
}
private bool CanPay(BasePlayer player, Dictionary<string, PriceInfo> prices, out string resources) {
var entries = new Hash<string, int>();
var language = RustTranslationAPI != null ? lang.GetLanguage(player.UserIDString) : null;
foreach (var entry in prices) {
if (entry.Value.amount <= 0) {
continue;
}
int missingAmount;
var itemDefinition = ItemManager.FindItemDefinition(entry.Key);
if (itemDefinition != null) {
missingAmount = entry.Value.amount - player.inventory.GetAmount(itemDefinition.itemid);
}
else {
missingAmount = CheckBalance(entry.Key, entry.Value.amount, player.userID.Get());
}
if (missingAmount <= 0) {
continue;
}
var displayName = GetItemDisplayName(language, entry.Key, entry.Value.displayName);
entries[displayName] += missingAmount;
}
if (entries.Count > 0) {
var stringBuilder = new StringBuilder();
foreach (var entry in entries) {
stringBuilder.AppendLine($"* {Lang("PriceFormat", player.UserIDString, entry.Key, entry.Value)}");
}
resources = stringBuilder.ToString();
return false;
}
resources = null;
return true;
}
private int CheckBalance(string key, int price, ulong playerId) {
switch (key.ToLower()) {
case "economics" : var balance = Economics?.Call("Balance", playerId);
if (balance is double) {
var n = price - (double)balance;
return n <= 0 ? 0 : (int)Math.Ceiling(n);
}
return price;
case "serverrewards" : var points = ServerRewards?.Call("CheckPoints", playerId);
if (points is int) {
var n = price - (int)points;
return n <= 0 ? 0 : n;
}
return price;
default : PrintError($"Unknown Currency Type '{key}'");
return price;
}
}
#endregion TryPay
#region AreFriends
private bool AreFriends(ulong playerId, ulong friendId) {
if (playerId == friendId) {
return true;
}
if (configData.global.useTeams && SameTeam(playerId, friendId)) {
return true;
}
if (configData.global.useFriends && HasFriend(playerId, friendId)) {
return true;
}
if (configData.global.useClans && SameClan(playerId, friendId)) {
return true;
}
return false;
}
private static bool SameTeam(ulong playerId, ulong friendId) {
if (!RelationshipManager.TeamsEnabled()) {
return false;
}
var playerTeam = RelationshipManager.ServerInstance.FindPlayersTeam(playerId);
if (playerTeam == null) {
return false;
}
var friendTeam = RelationshipManager.ServerInstance.FindPlayersTeam(friendId);
if (friendTeam == null) {
return false;
}
return playerTeam == friendTeam;
}
private bool HasFriend(ulong playerId, ulong friendId) {
if (Friends == null) {
return false;
}
return (bool)Friends.Call("HasFriend", playerId, friendId);
}
private bool SameClan(ulong playerId, ulong friendId) {
if (Clans == null) {
return false;
}
//Clans
var isMember = Clans.Call("IsClanMember", playerId.ToString(), friendId.ToString());
if (isMember != null) {
return (bool)isMember;
}
//Rust:IO Clans
var playerClan = Clans.Call("GetClanOf", playerId);
if (playerClan == null) {
return false;
}
var friendClan = Clans.Call("GetClanOf", friendId);
if (friendClan == null) {
return false;
}
return playerClan == friendClan;
}
#endregion AreFriends
#region IsPlayerBlocked
private bool IsPlayerBlocked(BasePlayer player) {
if (NoEscape == null) {
return false;
}
if (configData.global.useRaidBlocker && IsRaidBlocked(player.UserIDString)) {
Print(player, Lang("RaidBlocked", player.UserIDString));
return true;
}
if (configData.global.useCombatBlocker && IsCombatBlocked(player.UserIDString)) {
Print(player, Lang("CombatBlocked", player.UserIDString));
return true;
}
return false;
}
private bool IsRaidBlocked(string playerId) {
return (bool)NoEscape.Call("IsRaidBlocked", playerId);
}
private bool IsCombatBlocked(string playerId) {
return (bool)NoEscape.Call("IsCombatBlocked", playerId);
}
private bool InZone(BasePlayer player) {
if (ZoneManager == null || !ZoneManager.IsLoaded) return false;
return configData.AntiSpawnZones.Any(x => (bool)ZoneManager?.Call("PlayerHasFlag", player, x.ToLower()));
}
#endregion IsPlayerBlocked
#region GetSettings
private BaseVehicleSettings GetBaseVehicleSettings(string vehicleType) {
BaseVehicleSettings settings;
return allVehicleSettings.TryGetValue(vehicleType, out settings) ? settings : null;
}
private BaseVehicleSettings GetBaseVehicleSettings(NormalVehicleType normalVehicleType) {
switch (normalVehicleType) {
case NormalVehicleType.Tugboat : return configData.normalVehicles.tugboat;
case NormalVehicleType.Rowboat : return configData.normalVehicles.rowboat;
case NormalVehicleType.RHIB : return configData.normalVehicles.rhib;
case NormalVehicleType.Sedan : return configData.normalVehicles.sedan;
case NormalVehicleType.HotAirBalloon : return configData.normalVehicles.hotAirBalloon;
case NormalVehicleType.ArmoredHotAirBalloon : return configData.normalVehicles.armoredHotAirBalloon;
case NormalVehicleType.MiniCopter : return configData.normalVehicles.miniCopter;
case NormalVehicleType.AttackHelicopter : return configData.normalVehicles.attackHelicopter;
case NormalVehicleType.TransportHelicopter : return configData.normalVehicles.transportHelicopter;
case NormalVehicleType.Chinook : return configData.normalVehicles.chinook;
case NormalVehicleType.RidableHorse : return configData.normalVehicles.ridableHorse;
case NormalVehicleType.WorkCart : return configData.normalVehicles.workCart;
case NormalVehicleType.SedanRail : return configData.normalVehicles.sedanRail;
case NormalVehicleType.MagnetCrane : return configData.normalVehicles.magnetCrane;
case NormalVehicleType.SubmarineSolo : return configData.normalVehicles.submarineSolo;
case NormalVehicleType.SubmarineDuo : return configData.normalVehicles.submarineDuo;
case NormalVehicleType.Snowmobile : return configData.normalVehicles.snowmobile;
case NormalVehicleType.TomahaSnowmobile : return configData.normalVehicles.tomahaSnowmobile;
case NormalVehicleType.PedalBike : return configData.normalVehicles.pedalBike;
case NormalVehicleType.PedalTrike : return configData.normalVehicles.pedalTrike;
case NormalVehicleType.MotorBike : return configData.normalVehicles.motorBike;
case NormalVehicleType.MotorBike_SideCar : return configData.normalVehicles.motorBikeSidecar;
case NormalVehicleType.Kayak : return configData.normalVehicles.Kayak;
default : return null;
}
}
private BaseVehicleSettings GetCustomVehicleSettings(CustomVehicleType normalVehicleType) {
switch (normalVehicleType) {
case CustomVehicleType.ATV : return configData.customVehicles.atv;
case CustomVehicleType.RaceSofa : return configData.customVehicles.raceSofa;
case CustomVehicleType.WaterBird : return configData.customVehicles.waterBird;
case CustomVehicleType.WarBird : return configData.customVehicles.warBird;
case CustomVehicleType.LittleBird : return configData.customVehicles.littleBird;
case CustomVehicleType.Fighter : return configData.customVehicles.fighter;
case CustomVehicleType.OldFighter : return configData.customVehicles.oldFighter;
case CustomVehicleType.FighterBus : return configData.customVehicles.fighterBus;
case CustomVehicleType.WarBus : return configData.customVehicles.warBus;
case CustomVehicleType.AirBus : return configData.customVehicles.airBus;
case CustomVehicleType.PatrolHeli : return configData.customVehicles.patrolHeli;
case CustomVehicleType.RustWing : return configData.customVehicles.rustWing;
case CustomVehicleType.RustWingDetailed : return configData.customVehicles.rustWingDetailed;
case CustomVehicleType.RustWingDetailedOld : return configData.customVehicles.rustWingDetailedOld;
case CustomVehicleType.TinFighter : return configData.customVehicles.tinFighter;
case CustomVehicleType.TinFighterDetailed : return configData.customVehicles.tinFighterDetailed;
case CustomVehicleType.TinFighterDetailedOld : return configData.customVehicles.tinFighterDetailedOld;
case CustomVehicleType.MarsFighter : return configData.customVehicles.marsFighter;
case CustomVehicleType.MarsFighterDetailed : return configData.customVehicles.marsFighterDetailed;
case CustomVehicleType.SkyPlane : return configData.customVehicles.skyPlane;
case CustomVehicleType.SkyBoat : return configData.customVehicles.skyBoat;
case CustomVehicleType.TwistedTruck : return configData.customVehicles.twistedTruck;
case CustomVehicleType.TrainWreck : return configData.customVehicles.trainWreck;
case CustomVehicleType.TrainWrecker : return configData.customVehicles.trainWrecker;
case CustomVehicleType.Santa : return configData.customVehicles.santa;
case CustomVehicleType.WarSanta : return configData.customVehicles.warSanta;
case CustomVehicleType.Witch : return configData.customVehicles.witch;
case CustomVehicleType.MagicCarpet : return configData.customVehicles.magicCarpet;
case CustomVehicleType.Ah69t : return configData.customVehicles.ah69t;
case CustomVehicleType.Ah69r : return configData.customVehicles.ah69r;
case CustomVehicleType.Ah69a : return configData.customVehicles.ah69a;
case CustomVehicleType.Mavik : return configData.customVehicles.mavik;
case CustomVehicleType.HeavyFighter : retur
// ... [Code preview truncated due to length. Full source in attached file] ...