C#:
using Rust;
using System.Reflection;
using Facepunch;
using Newtonsoft.Json;
using CompanionServer.Handlers;
using Oxide.Core.Plugins;
using Oxide.Plugins.JetPackExtensionMethods;
using Oxide.Core;
using UnityEngine;
using System.Collections.Generic;
using System;
using System.Collections;
namespace Oxide.Plugins.JetPackExtensionMethods {
public static class ExtensionMethods {
public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
using (var enumerator = source.GetEnumerator()) while (enumerator.MoveNext()) if (predicate(enumerator.Current)) return true;
return false;
}
public static HashSet<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
HashSet<TSource> result = new HashSet<TSource>();
using (var enumerator = source.GetEnumerator()) while (enumerator.MoveNext()) if (predicate(enumerator.Current)) result.Add(enumerator.Current);
return result;
}
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
using (var enumerator = source.GetEnumerator()) while (enumerator.MoveNext()) if (predicate(enumerator.Current)) return enumerator.Current;
return default(TSource);
}
public static HashSet<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> predicate) {
HashSet<TResult> result = new HashSet<TResult>();
using (var enumerator = source.GetEnumerator()) while (enumerator.MoveNext()) result.Add(predicate(enumerator.Current));
return result;
}
public static List<TResult> Select<TSource, TResult>(this IList<TSource> source, Func<TSource, TResult> predicate) {
List<TResult> result = new List<TResult>();
for (int i = 0; i < source.Count; i++) {
TSource element = source[i];
result.Add(predicate(element));
}
return result;
}
public static HashSet<T> OfType<T>(this IEnumerable<BaseNetworkable> source) {
HashSet<T> result = new HashSet<T>();
using (var enumerator = source.GetEnumerator()) while (enumerator.MoveNext()) if (enumerator.Current is T) result.Add((T)(object)enumerator.Current);
return result;
}
public static bool IsExists(this BaseNetworkable entity) => entity != null && !entity.IsDestroyed;
public static void ClearItemsContainer(this ItemContainer container) {
for (int i = container.itemList.Count - 1; i >= 0; i--) {
Item item = container.itemList[i];
item.RemoveFromContainer();
item.Remove();
}
}
public static bool IsRealPlayer(this BasePlayer player) => player != null && player.userID.IsSteamId();
public static List<TSource> OrderBy<TSource>(this IEnumerable<TSource> source, Func<TSource, float> predicate) {
List<TSource> result = source.ToList();
for (int i = 0; i < result.Count; i++) {
for (int j = 0; j < result.Count - 1; j++) {
if (predicate(result[j]) > predicate(result[j + 1])) {
TSource z = result[j];
result[j] = result[j + 1];
result[j + 1] = z;
}
}
}
return result;
}
public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source) {
List<TSource> result = new List<TSource>();
using (var enumerator = source.GetEnumerator()) while (enumerator.MoveNext()) result.Add(enumerator.Current);
return result;
}
public static HashSet<TSource> ToHashSet<TSource>(this IEnumerable<TSource> source) {
HashSet<TSource> result = new HashSet<TSource>();
using (var enumerator = source.GetEnumerator()) while (enumerator.MoveNext()) result.Add(enumerator.Current);
return result;
}
public static TSource Max<TSource>(this IEnumerable<TSource> source, Func<TSource, float> predicate) {
TSource result = source.ElementAt(0);
float resultValue = predicate(result);
using (var enumerator = source.GetEnumerator()) {
while (enumerator.MoveNext()) {
TSource element = enumerator.Current;
float elementValue = predicate(element);
if (elementValue > resultValue) {
result = element;
resultValue = elementValue;
}
}
}
return result;
}
public static TSource Min<TSource>(this IEnumerable<TSource> source, Func<TSource, float> predicate) {
TSource result = source.ElementAt(0);
float resultValue = predicate(result);
using (var enumerator = source.GetEnumerator()) {
while (enumerator.MoveNext()) {
TSource element = enumerator.Current;
float elementValue = predicate(element);
if (elementValue < resultValue) {
result = element;
resultValue = elementValue;
}
}
}
return result;
}
public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index) {
int movements = 0;
using (var enumerator = source.GetEnumerator()) {
while (enumerator.MoveNext()) {
if (movements == index) return enumerator.Current;
movements++;
}
}
return default(TSource);
}
public static TSource First<TSource>(this IList<TSource> source) => source[0];
public static TSource Last<TSource>(this IList<TSource> source) => source[source.Count - 1];
}
}
namespace Oxide.Plugins {
[Info("JetPack", "Adem", "1.2.8")]
class JetPack : RustPlugin {
void OnSamSiteTargetScan(SamSite samSite, List<SamSite.ISamSiteTarget> targetList) {
if (samSite == null || targetList == null) return;
if (samSite.IsInDefenderMode()) return;
if (_config.isPlayerSamsWiillAttack || _config.isMonumentSamsWillAttack) JetpackComponent.AddAllJetpacksToSamTargetList(samSite, targetList);
}
static string GetMessage(string langKey, string userID, params object[] args) => (args.Length == 0) ? GetMessage(langKey, userID) : string.Format(GetMessage(langKey, userID), args);
[ConsoleCommand("givejetpack")]
void GiveJetpackConsoleCommand(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (player == null) {
if (arg.Args == null || arg.Args.Length < 1) return;
BasePlayer target = BasePlayer.FindByID(Convert.ToUInt64(arg.Args[0]));
if (target == null) {
Puts("Player not found");
return;
}
LootManager.GiveJetpackItemToPlayer(target);
NotifyManager.SendMessageToPlayer(target, "GetJetpack", ins._config.prefix);
Puts($"A jetpack was given to {target.displayName}!");
}
}
object CanLootEntity(BasePlayer player, SupplyDrop container) {
if (player == null) return null;
if (!_config.isAllowedLootAirdrop) {
JetpackComponent jetPack = JetpackComponent.GetJetpackComponentByUserId(player.userID);
if (jetPack != null) return true;
}
return null;
}
private PluginConfig _config;
class SeekerTargetComponent : FacepunchBehaviour, SeekerTarget.ISeekerTargetOwner {
MovableDroppedItem movableDroppedItem;
internal static SeekerTargetComponent AttachSeekerTargetComponent(MovableDroppedItem movableDroppedItem) {
if (!ins._config.homingLauncherConfig.isEnable) return null;
GameObject gameObject = new GameObject("SeekerTargetComponent");
gameObject.transform.SetParent(movableDroppedItem.transform, false);
SeekerTargetComponent seekerTargetComponent = gameObject.AddComponent<SeekerTargetComponent>();
seekerTargetComponent.Init(movableDroppedItem);
return seekerTargetComponent;
}
void Init(MovableDroppedItem movableDroppedItem) {
this.movableDroppedItem = movableDroppedItem;
SeekerTarget.SeekerStrength seekerStrength = ins._config.homingLauncherConfig.targetCaptureDistance == 0 ? SeekerTarget.SeekerStrength.LOW : ins._config.homingLauncherConfig.targetCaptureDistance == 1 ? SeekerTarget.SeekerStrength.MEDIUM : SeekerTarget.SeekerStrength.HIGH;
SeekerTarget.SetSeekerTarget(this, seekerStrength);
}
public bool InSafeZone() {
return movableDroppedItem.InSafeZone();
}
public bool IsValidHomingTarget() {
return true;
}
public void OnEntityMessage(BaseEntity from, string msg) {
}
public Vector3 CenterPoint() {
return movableDroppedItem.WorldSpaceBounds().position;
}
public bool IsVisible(Vector3 position, float maxDistance = float.PositiveInfinity) {
return movableDroppedItem.IsVisibleAndCanSee(position) || movableDroppedItem.children.Any(x => x != null && x.IsVisibleAndCanSee(position));
}
internal void KillComponent() {
if (this.gameObject != null) UnityEngine.GameObject.Destroy(this.gameObject);
}
}
protected override void LoadConfig() {
base.LoadConfig();
_config = Config.ReadObject<PluginConfig>();
Config.WriteObject(_config, true);
}
class JetpackComponent : FacepunchBehaviour {
void BuildJetpack() {
SpawnChair();
SpawnDecorEntities();
CreateCollider();
}
void Update() {
if (ins._config.isSoundEnabled && !ins._config.isQuiteSound) Sound();
}
static void CreateJetpack(BasePlayer player) {
MovableDroppedItem movableDroppedItem = MovableDroppedItem.CreateMovableDroppedItem(player.transform.position + new Vector3(0, 1.3f, 0), Quaternion.Euler(0, player.eyes.GetLookRotation().eulerAngles.y, 0));
JetpackComponent jetpackComponent = movableDroppedItem.gameObject.AddComponent<JetpackComponent>();
jetpackComponent.Init(player, movableDroppedItem);
jetpacks.Add(jetpackComponent);
jetpacks.RemoveWhere(x => x == null);
}
IEnumerator QuiteSoundCorountine() {
while (true) {
if (flamethrowers.Count > 0) Effect.server.Run("assets/bundled/prefabs/fx/impacts/blunt/sand/sand.prefab", player.transform.position);
yield return CoroutineEx.waitForSeconds(0.2f);
}
}
static bool IsBuildingsInDirection(Vector3 origin, Vector3 direction) {
RaycastHit raycastHit;
return Physics.Raycast(origin, direction, out raycastHit, 2, 1 << 21 | 1 << 8);
}
void AutoHorizont() {
if (isGrounded) return;
float horizonAngle = Vector3.Angle(transform.right, new Vector3(transform.right.x, 0, transform.right.z));
bool right = transform.right.y < 0;
if (right) horizonAngle *= -1;
rigidbody.AddTorque(-transform.forward * horizonAngle * 5);
}
MovableDroppedItem movableDroppedItem;
static BUTTON ForceButton = BUTTON.JUMP;
bool haveFuel = true;
IEnumerator WeaponHoldBlockCorountine() {
while (true) {
if (isGrounded && LootManager.IsPositionNearToSupplyDrop(transform.position)) RemoveJetpack();
yield return CoroutineEx.waitForSeconds(1f);
}
}
Coroutine soundCorountine;
void CreateFireGun(Vector3 localPosition, Vector3 localRotation) {
BaseEntity entity = BuildManager.CreateChildEntity(movableDroppedItem, "assets/prefabs/weapons/military flamethrower/militaryflamethrower.entity.prefab", localPosition, localRotation);
entity.SetFlag(BaseEntity.Flags.Reserved8, true);
flamethrowers.Add(entity);
}
void OnGrounded() {
if (!isGrounded) {
isGrounded = true;
rigidbody.maxAngularVelocity = 0.5f;
}
}
static bool IsPlayerAtHome(BasePlayer player) {
if (SupportedPluginsController.CheckBySpacePlugin(player)) return true;
Vector3 originPosition = player.transform.position + new Vector3(0, 1.5f, 0);
if (IsBuildingsInDirection(originPosition, Vector3.up)) return true;
else if (IsBuildingsInDirection(originPosition, player.eyes.BodyForward()) || IsBuildingsInDirection(originPosition, -player.eyes.BodyForward())) return true;
else if (IsBuildingsInDirection(originPosition, player.eyes.BodyRight()) || IsBuildingsInDirection(originPosition, -player.eyes.BodyRight())) return true;
return false;
}
void OnDestroy() {
chair.DismountPlayer(player, true);
if (soundCorountine != null) ServerMgr.Instance.StopCoroutine(soundCorountine);
if (weaponHoldBlockCorountine != null) ServerMgr.Instance.StopCoroutine(weaponHoldBlockCorountine);
if (player != null) player.SetPlayerFlag(BasePlayer.PlayerFlags.ThirdPersonViewmode, false);
if (seekerTargetComponent != null) seekerTargetComponent.KillComponent();
Interface.CallHook("OnJetpackRemoved", new object[] {
player
}
);
}
void EnableFireEffects() {
if (flamethrowers.Count > 0 || !haveFuel) return;
CreateFireGun(new Vector3(0.118f, 0.206f, 0f), new Vector3(355.290f, 270.032f, 89.903f));
CreateFireGun(new Vector3(-0.129f, 0.208f, 0.061f), new Vector3(355.290f, 90.032f, 89.903f));
}
internal bool IsPlayerCanTakeOffJetpack() {
return ins._config.isAirTakeOffAllowed || IsJetpackOnTheGround() || IsJetpackOnCargoShip() || SupportedPluginsController.IsPositionInSpace(transform.position);
}
bool isGrounded = false;
void ControlRotation() {
float rotateSpeedMultiplicator = 1;
if (player.serverInput.IsDown(BUTTON.FORWARD)) transform.RotateAround(transform.position, transform.right, ins._config.control.upDown * rotateSpeedMultiplicator);
else if (player.serverInput.IsDown(BUTTON.BACKWARD)) transform.RotateAround(transform.position, transform.right, -ins._config.control.upDown * rotateSpeedMultiplicator);
if (player.serverInput.IsDown(BUTTON.RIGHT)) transform.RotateAround(transform.position, Vector3.up, ins._config.control.yaw * rotateSpeedMultiplicator);
else if (player.serverInput.IsDown(BUTTON.LEFT)) transform.RotateAround(transform.position, Vector3.up, -ins._config.control.yaw * rotateSpeedMultiplicator);
if (ins._config.control.autoCrenHold) {
AutoHorizont();
}
else {
if (player.serverInput.IsDown(BUTTON.DUCK)) transform.RotateAround(transform.position, transform.forward, ins._config.control.cren * rotateSpeedMultiplicator);
else if (player.serverInput.IsDown(BUTTON.SPRINT)) transform.RotateAround(transform.position, transform.forward, -ins._config.control.cren * rotateSpeedMultiplicator);
}
}
void SpawnChair() {
string chairPrefabName = ins._config.isWeaponAllowed ? "assets/prefabs/vehicle/seats/testseat.prefab" : "assets/prefabs/vehicle/seats/standingdriver.prefab";
Vector3 localPosition = new Vector3(0, -1.18f, 0.25f);
Vector3 localRotation = new Vector3(0, -5f, 0);
chair = MovableBaseMountable.CreateMovableBaseMountable(movableDroppedItem, chairPrefabName, localPosition, localRotation);
chair.MountPlayer(player);
if (ins._config.isThirdPersonView) player.SetPlayerFlag(BasePlayer.PlayerFlags.ThirdPersonViewmode, true);
}
SeekerTargetComponent seekerTargetComponent;
void OnCollisionExit(Collision collision) {
OnTakeOff();
}
void OnCollisionStay(Collision collision) {
OnGrounded();
}
void CheckFall() {
if (!ins._config.isFallDamageEnabled) return;
float deltaSpeed = Math.Abs(rigidbody.velocity.magnitude - lastSpeed);
if (deltaSpeed > ins._config.fallDamagePoint) player.Hurt((deltaSpeed - ins._config.fallDamagePoint) * ins._config.fallDamageMultiplicator, DamageType.Fall, null, false);
lastSpeed = rigidbody.velocity.magnitude;
}
Coroutine weaponHoldBlockCorountine;
internal static void AddAllJetpacksToSamTargetList(SamSite samSite, List<SamSite.ISamSiteTarget> targetList) {
foreach (JetpackComponent jetPackComponent in jetpacks) {
if (jetPackComponent == null || jetPackComponent.player == null) continue;
BuildingPrivlidge buildingPrivlidge = samSite.GetBuildingPrivilege();
if (buildingPrivlidge != null && buildingPrivlidge.IsAuthed(jetPackComponent.player)) continue;
if (samSite.ShortPrefabName == "sam_static") {
if (ins._config.isMonumentSamsWillAttack) targetList.Add(jetPackComponent.samSiteComponent);
continue;
}
else if (ins._config.isPlayerSamsWiillAttack) {
targetList.Add(jetPackComponent.samSiteComponent);
}
}
}
internal static void RemoveJetpackFromPlayer(ulong playerUserId) {
JetpackComponent jetPack = JetpackComponent.GetJetpackComponentByUserId(playerUserId);
if (jetPack != null) jetPack.RemoveJetpack();
}
SAMTargetComponent samSiteComponent;
private class SAMTargetComponent : FacepunchBehaviour, SamSite.ISamSiteTarget {
public bool IsValidSAMTarget(bool isStaticSamSite) => true;
public Vector3 CenterPoint() => transform.position;
BaseEntity baseEntity;
Rigidbody rigidbody;
public Vector3 Position => baseEntity.transform.position;
public bool isClient => false;
public bool IsValidSAMTarget() => true;
public Vector3 GetWorldVelocity() {
return rigidbody.velocity;
}
public SamSite.SamTargetType SAMTargetType => ins._config.isSamsRadiusAndSpeedIncreased ? SamSite.targetTypeMissile : SamSite.targetTypeVehicle;
public bool IsVisible(Vector3 position, float distance) => baseEntity.IsVisible(position, distance);
private void Awake() {
baseEntity = GetComponent<BaseEntity>();
rigidbody = GetComponent<Rigidbody>();
}
}
Rigidbody rigidbody;
void SpawnDecorEntities() {
BuildManager.CreateChildEntity(movableDroppedItem, "assets/prefabs/weapons/rocketlauncher/rocket_launcher.entity.prefab", new Vector3(-0.160f, -0.221f, 0.186f), new Vector3(6.413f, 0.312f, 38.265f));
BuildManager.CreateChildEntity(movableDroppedItem, "assets/prefabs/weapons/rocketlauncher/rocket_launcher.entity.prefab", new Vector3(0.292f, -0.221f, 0.186f), new Vector3(6.413f, 0.312f, 38.265f));
}
void OnTakeOff() {
if (isGrounded) {
isGrounded = false;
rigidbody.maxAngularVelocity = 7;
}
}
float lastSpeed = 0;
List<BaseEntity> flamethrowers = new List<BaseEntity>();
static bool IsPlayerCanWearJetpack(BasePlayer player) {
if (player.HasPlayerFlag(BasePlayer.PlayerFlags.Wounded)) return false;
if (player.isMounted) return false;
JetpackComponent jetPackComponent = GetJetpackComponentByUserId(player.userID);
if (jetPackComponent != null) return false;
if (!ins._config.isAirEquipfAllowed && !player.IsOnGround()) {
NotifyManager.SendMessageToPlayer(player, "AirEquipBlock", ins._config.prefix);
return false;
}
if (LootManager.IsPlayerHaveJetItem(player)) {
if (!ins.permission.UserHasPermission(player.UserIDString, ins._config.permissionForUse) && !ins.permission.UserHasPermission(player.UserIDString, ins._config.permissionJetpackCommand)) {
NotifyManager.SendMessageToPlayer(player, "NoPermission", ins._config.prefix);
return false;
}
}
else if (!ins.permission.UserHasPermission(player.UserIDString, ins._config.permissionJetpackCommand)) {
return false;
}
if (IsPlayerAtHome(player)) {
NotifyManager.SendMessageToPlayer(player, "AtHome", ins._config.prefix);
return false;
}
else if (!SupportedPluginsController.IsZoneManagerAllowJetpackUse(player)) {
NotifyManager.SendMessageToPlayer(player, "AreaBlock", ins._config.prefix);
return false;
}
return true;
}
internal bool IsJetpackOnTheGround() {
return isGrounded;
}
internal bool IsJetpackOnCargoShip() {
foreach (Collider collider in UnityEngine.Physics.OverlapSphere(transform.position, 2f)) {
BaseEntity entity = collider.ToBaseEntity();
if (entity == null) continue;
else if (entity is CargoShip) return true;
}
return false;
}
BasePlayer player;
void ControlFuelConsumtion() {
if (ins._config.fuel.fuelPerTick <= 0 || infinityFuel) return;
float timeScienceLastConsumtion = UnityEngine.Time.realtimeSinceStartup - lastFuelConsumtionTime;
if (timeScienceLastConsumtion >= 2) {
List<Item> allItems = Pool.Get<List<Item>>();
player.inventory.GetAllItems(allItems);
Item item = allItems.FirstOrDefault(x => x != null && LootManager.IsFuelItem(x.info.shortname));
Pool.FreeUnmanaged(ref allItems);
if (item == null) {
if (haveFuel) {
NotifyManager.SendMessageToPlayer(player, "NoFuel", ins._config.prefix);
haveFuel = false;
DisableFireEffects();
}
return;
}
lastFuelConsumtionTime = UnityEngine.Time.realtimeSinceStartup;
targetConsumtionAmount += ins._config.fuel.fuelPerTick;
int consumtionInInt = (int)targetConsumtionAmount;
if (consumtionInInt > 0) {
targetConsumtionAmount -= consumtionInInt;
if (item.amount > consumtionInInt) {
item.amount = item.amount - consumtionInInt;
item.MarkDirty();
haveFuel = true;
}
else {
item.Remove();
}
}
}
}
float targetConsumtionAmount = 0;
void DisableFireEffects() {
if (flamethrowers.Count == 0) return;
foreach (BaseEntity entity in flamethrowers) entity.Kill();
flamethrowers.Clear();
}
internal static JetpackComponent GetJetpackComponentByUserId(ulong userId) {
return jetpacks.FirstOrDefault(x => x != null && x.player.userID == userId);
}
void GetAndUpdateRigidbody() {
rigidbody = gameObject.GetComponent<Rigidbody>();
rigidbody.drag = ins._config.control.drag;
rigidbody.centerOfMass = new Vector3(0, -1.1f, 0.25f);
rigidbody.mass = 100;
rigidbody.angularDrag = 3;
rigidbody.maxAngularVelocity = 7;
}
void ControlEngine() {
if (!haveFuel) {
ControlFuelConsumtion();
return;
}
if (player.serverInput.IsDown(ForceButton)) {
ControlFuelConsumtion();
EnableFireEffects();
if (transform.position.y < ins._config.maxHeight || SupportedPluginsController.IsPositionInSpace(transform.position)) rigidbody.AddForce(transform.up * ins._config.control.force * 100, ForceMode.Force);
}
else {
DisableFireEffects();
}
}
static HashSet<JetpackComponent> jetpacks = new HashSet<JetpackComponent>();
void CreateCollider() {
CapsuleCollider capsuleCollider = chair.gameObject.AddComponent<CapsuleCollider>();
capsuleCollider.gameObject.layer = 12;
capsuleCollider.direction = 1;
capsuleCollider.center = new Vector3(0, 0.95f, 0);
capsuleCollider.height = 2f;
capsuleCollider.radius = 0.75f;
capsuleCollider.material.staticFriction = 1;
capsuleCollider.material.dynamicFriction = 1;
capsuleCollider.material.frictionCombine = PhysicMaterialCombine.Maximum;
}
void Init(BasePlayer player, MovableDroppedItem movableDroppedItem) {
this.player = player;
this.movableDroppedItem = movableDroppedItem;
GetAndUpdateRigidbody();
BuildJetpack();
Interface.CallHook("OnJetpackWear", new object[] {
player
}
);
if (ins.permission.UserHasPermission(player.UserIDString, ins._config.permissionForNoFuel)) infinityFuel = true;
if (ins._config.isPlayerSamsWiillAttack || ins._config.isMonumentSamsWillAttack) samSiteComponent = gameObject.AddComponent<SAMTargetComponent>();
if (ins._config.isSoundEnabled && ins._config.isQuiteSound) soundCorountine = ServerMgr.Instance.StartCoroutine(QuiteSoundCorountine());
if (ins._config.isWeaponAllowed) weaponHoldBlockCorountine = ServerMgr.Instance.StartCoroutine(WeaponHoldBlockCorountine());
seekerTargetComponent = SeekerTargetComponent.AttachSeekerTargetComponent(movableDroppedItem);
}
bool CheckPasanger() {
if (!chair.PlayerIsMounted(player) || player.IsSleeping()) return false;
return true;
}
bool infinityFuel = false;
float lastFuelConsumtionTime = 0;
void SpacePluginController() {
if (SupportedPluginsController.isSpaceEventActive) {
if (SupportedPluginsController.IsPositionInSpace(player.transform.position)) {
if (rigidbody.useGravity) rigidbody.useGravity = false;
}
else if (!rigidbody.useGravity) rigidbody.useGravity = true;
}
else if (!rigidbody.useGravity) rigidbody.useGravity = true;
}
void Sound() {
if (flamethrowers.Count > 0) Effect.server.Run("assets/bundled/prefabs/fx/impacts/blunt/sand/sand.prefab", player.transform.position);
}
internal static void RemoveAllJetpacks() {
foreach (JetpackComponent jetpack in jetpacks) if (jetpack != null) jetpack.RemoveJetpack(true);
}
internal void PlayerWantsTakeOffJetpack() {
if (IsPlayerCanTakeOffJetpack()) RemoveJetpack();
}
void FixedUpdate() {
if (!CheckPasanger()) {
RemoveJetpack();
return;
}
ControlEngine();
ControlRotation();
CheckFall();
CheckWater();
SpacePluginController();
}
internal static void OnPlayerEnterJetCommand(BasePlayer player) {
JetpackComponent jetPack = JetpackComponent.GetJetpackComponentByUserId(player.userID);
if (jetPack != null) jetPack.PlayerWantsTakeOffJetpack();
else JetpackComponent.TryAttachJetpackToPlayer(player);
}
internal static JetpackComponent GetJetDroppedItemNetId(ulong netId) {
return jetpacks.FirstOrDefault(x => x != null && x.movableDroppedItem.net.ID.Value == netId);
}
internal static void TryAttachJetpackToPlayer(BasePlayer player) {
if (IsPlayerCanWearJetpack(player)) CreateJetpack(player);
}
internal void RemoveJetpack(bool removeAllJetpacks = false) {
movableDroppedItem.Kill();
if (!removeAllJetpacks) jetpacks.Remove(this);
}
BaseMountable chair;
void CheckWater() {
if (ins._config.isTakeOffJetInWater && WaterLevel.Test(movableDroppedItem.transform.position, true, true)) RemoveJetpack();
}
}
public class CrateConfig {
[JsonProperty(en ? "Prefab" : "Префаб ящика")]
public string Prefab {
get;
set;
}
[JsonProperty(en ? "Chance" : "Шанс")]
public float Chance {
get;
set;
}
}
sealed class MovableDroppedItem : DroppedItem {
internal static MovableDroppedItem CreateMovableDroppedItem(Vector3 position, Quaternion rotation) {
DroppedItem droppedItem = GameManager.server.CreateEntity("assets/prefabs/misc/burlap sack/generic_world.prefab", position, rotation) as DroppedItem;
droppedItem.enableSaving = false;
droppedItem.allowPickup = false;
droppedItem.item = ItemManager.CreateByName("largebackpack");
MovableDroppedItem movableDroppedItem = droppedItem.gameObject.AddComponent<MovableDroppedItem>();
BuildManager.CopySerializableFields(droppedItem, movableDroppedItem);
droppedItem.StopAllCoroutines();
UnityEngine.GameObject.DestroyImmediate(droppedItem, true);
movableDroppedItem.Spawn();
movableDroppedItem.allowPickup = false;
movableDroppedItem.SetFlag(BaseEntity.Flags.Busy, true);
movableDroppedItem.SetFlag(BaseEntity.Flags.Locked, true);
return movableDroppedItem;
}
public override float MaxVelocity() {
return 100;
}
public override float GetDespawnDuration() {
return float.MaxValue;
}
}
void OnItemRemovedFromContainer(ItemContainer container, Item item) {
if (container == null || item == null) return;
if (LootManager.IsJetpackItem(item)) {
BasePlayer player = container.playerOwner;
if (player.IsRealPlayer() && container == player.inventory.containerWear) JetpackComponent.RemoveJetpackFromPlayer(player.userID);
}
}
public class ZoneManagerConfig {
[JsonProperty(en ? "Do you use the ZoneManager? [true/false]" : "Использовать ли ZoneManager? [true/false]")]
public bool enable {
get;
set;
}
[JsonProperty(en ? "List of zone flags that block spawn" : "Список флагов, при наличии в зоне которого спутник не будет спавниться")]
public HashSet<string> blockFlags {
get;
set;
}
[JsonProperty(en ? "List of zone IDs that block spawn" : "Список ID зон, которые запретят спавн спутника")]
public HashSet<string> blockIDs {
get;
set;
}
}
protected override void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["GetJetpack"]
= "{0} You <color=#738d43>got</color> a jetpack!", ["NoPermission"] = "{0} You <color=#b03b1e>do not have permission</color> to use a jetpack!", ["AtHome"] = "{0} You <color=#b03b1e>cannot</color> use a jetpack indoors!", ["AirEquipBlock"] = "{0} It is <color=#b03b1e>forbidden</color> to equip a jetpack in the air!", ["NoFuel"] = "{0} To use the jetpack, put fuel to <color=#738d43>inventory</color>!", ["CommandBlock"] = "{0} This command is <color=#b03b1e>not allowed</color> to be used with a jetpack!", ["AreaBlock"] = "{0} It is <color=#b03b1e>forbidden</color> to use a jetpack in this area!", ["ActivateCommand"] = "{0} To activate the jetpack, use the command <color=#738d43>/jet</color>",
}
, this);
lang.RegisterMessages(new Dictionary<string, string> {
["GetJetpack"]
= "{0} Вы <color=#738d43>получили</color> реактивный ранец!", ["NoPermission"] = "{0} У вас <color=#b03b1e>нет разрешения</color> использовать реактивный ранец!", ["AtHome"] = "{0} <color=#b03b1e>Запрещено</color> использовать реактивный ранец в помещении!", ["AirEquipBlock"] = "{0} <color=#b03b1e>Запрещено</color> надевать джетпак в воздухе!", ["NoFuel"] = "{0} Для использования реактивного ранца положите топливо в <color=#2257b3>инвентарь</color>!", ["CommandBlock"] = "{0} Эту команду <color=#b03b1e>запрещено</color> использовать на джетпаке!", ["AreaBlock"] = "{0} <color=#b03b1e>Запрещено</color> использовать джетпак в этой области!", ["ActivateCommand"] = "{0} Для активации джетпака используйте команду <color=#738d43>/jet</color>!",
}
, this, "ru");
}
void Unsubscribes() {
foreach (string hook in subscribeMetods) Unsubscribe(hook);
}
void OnSpaceEventStart() {
SupportedPluginsController.spaceHeight = (float)Space.Call("GetMinSpaceAltitude");
SupportedPluginsController.isSpaceEventActive = true;
}
[PluginReference]
private Plugin ZoneManager, Space;
const bool en = false;
void OnEntitySpawned(SupplyDrop supplyDrop) {
if (supplyDrop == null) return;
LootManager.OnSuplyDropSpawned(supplyDrop);
}
static class NotifyManager {
internal static void PrintErrorToConsole(string langKey, params object[] args) {
string langMessage = GetMessage(langKey, null, args);
string consoleMessage = ClearColorAndSize(langMessage);
ins.PrintError(consoleMessage);
}
internal static string ClearColorAndSize(string message) {
message = message.Replace("</color>", string.Empty);
message = message.Replace("</size>", string.Empty);
while (message.Contains("<color=")) {
int index = message.IndexOf("<color=");
message = message.Remove(index, message.IndexOf(">", index) - index + 1);
}
while (message.Contains("<size=")) {
int index = message.IndexOf("<size=");
message = message.Remove(index, message.IndexOf(">", index) - index + 1);
}
return message;
}
internal static void SendMessageToPlayer(BasePlayer player, string langKey, params object[] args) {
if (ins._config.notificationConfig.isChat) ins.PrintToChat(player, GetMessage(langKey, player.UserIDString, args));
}
}
void OnLootSpawn(LootContainer container) {
if (container == null) return;
if (_config.isSpawnInLootEnabled) {
CrateConfig config = _config.crates.FirstOrDefault(x => x.Prefab == container.PrefabName);
if (config == null) return;
LootManager.TrySpawnItemInDefaultCrate(container, _config.itemConfig, config.Chance);
}
}
private class PluginConfig {
[JsonProperty(en ? "Version" : "Версия")]
public string version {
get;
set;
}
[JsonProperty(en ? "Prefix of chat messages" : "Префикс в чате")]
public string prefix {
get;
set;
}
[JsonProperty(en ? "Permission to use" : "Разрешение для использования")]
public string permissionForUse {
get;
set;
}
[JsonProperty(en ? "Permission to use a Jetpack without a Jetpack item in the inventory (chat command - /jet)" : "Разрешение для использования Джетпака без соответствующего предмета в инвентаре (команда - /jet)")]
public string permissionJetpackCommand {
get;
set;
}
[JsonProperty(en ? "Permission to give to yourself" : "Разрешение для выдачи себе")]
public string permissionForGiveSelf {
get;
set;
}
[JsonProperty(en ? "Permission to turn off fuel" : "Разрешение для отключения топлива")]
public string permissionForNoFuel {
get;
set;
}
[JsonProperty(en ? "Activate the jetpack when moving an item into a clothing container?" : "Активировать джетпак при перемещении предмета в контейнер одежды? ")]
public bool wearWhenItemAdded {
get;
set;
}
[JsonProperty(en ? "Allow the jetpack to be activated with the /jet command from any inventory container? (false - only from the clothing container)" : "Разрешить активировать джетпак командой /jet из любого контейнера инвентаря? (false - только из контейнера одежды)")]
public bool allowOpenFromAnyContainer {
get;
set;
}
[JsonProperty(en ? "Maximum flight altitude" : "Максимальная высота полета")]
public float maxHeight {
get;
set;
}
[JsonProperty(en ? "Allow the use of weapons on the jetpack?" : "Разрешить использование оружия на джетпаке?")]
public bool isWeaponAllowed {
get;
set;
}
[JsonProperty(en ? "Take off a jetpack in the water?" : "Снимать джетпак при попадании в воду")]
public bool isTakeOffJetInWater {
get;
set;
}
[JsonProperty(en ? "Allow to take off the jetpack in the air" : "Разрешить снимать джетпак в воздухе")]
public bool isAirTakeOffAllowed {
get;
set;
}
[JsonProperty(en ? "Allow to equip a jetpack in the air" : "Разрешить одевать джетпак в воздухе")]
public bool isAirEquipfAllowed {
get;
set;
}
[JsonProperty(en ? "Third-person view" : "Вид от третьего лица")]
public bool isThirdPersonView {
get;
set;
}
[JsonProperty(en ? "Turn on the sound?" : "Включить звук при полете")]
public bool isSoundEnabled {
get;
set;
}
[JsonProperty(en ? "Use quiet sound" : "Уменьшить громкость звука")]
public bool isQuiteSound {
get;
set;
}
[JsonProperty(en ? "Enable collision damage" : "Включить урон от столкновений")]
public bool isFallDamageEnabled {
get;
set;
}
[JsonProperty(en ? "Collision Damage Multiplier" : "Множитель урона от столкновений")]
public float fallDamageMultiplicator {
get;
set;
}
[JsonProperty(en ? "Collision acceleration threshold" : "Порог урона от столкновений")]
public float fallDamagePoint {
get;
set;
}
[JsonProperty(en ? "The SamSite will attack the jetpack" : "ПВО будет атаковать джетпак")]
public bool isPlayerSamsWiillAttack {
get;
set;
}
[JsonProperty(en ? "The SamSite on the monuments will attack the jetpack" : "ПВО на рт будет атаковать джетпак")]
public bool isMonumentSamsWillAttack {
get;
set;
}
[JsonProperty(en ? "Increased missile speed and SamSite attack radius by jetpack" : "Увеличеные скорость ракет и радиус атаки ПВО по джетпаку")]
public bool isSamsRadiusAndSpeedIncreased {
get;
set;
}
[JsonProperty(en ? "Homing Launcher Config" : "Настройки ПЗРК")]
public HomingLauncherConfig homingLauncherConfig {
get;
set;
}
[JsonProperty(en ? "Allow loot supply drop when using a jetpack" : "Разрешить лутать аирдроп при использовании джетпака")]
public bool isAllowedLootAirdrop {
get;
set;
}
[JsonProperty(en ? "List of commands that are prohibited while using the jetpack" : "Список команд, которые запрещены во время использования джетпака")]
public HashSet<string> blockedCommands {
get;
set;
}
[JsonProperty(en ? "Control" : "Управление")]
public ControlConfig control {
get;
set;
}
[JsonProperty(en ? "Fuel" : "Топливо")]
public FuelConfig fuel {
get;
set;
}
[JsonProperty(en ? "Item" : "Предмет")]
public ItemConfig itemConfig {
get;
set;
}
[JsonProperty(en ? "Enable spawn in crates" : "Включить спавн в ящиках")]
public bool isSpawnInLootEnabled {
get;
set;
}
[JsonProperty(en ? "Spawn setting" : "Настройка спавна в ящиках")]
public List<CrateConfig> crates {
get;
set;
}
[JsonProperty(en ? "Notification Settings" : "Настройкa уведомлений")]
public NotificationConfig notificationConfig {
get;
set;
}
[JsonProperty(en ? "Supported Plugins" : "Поддерживаемые плагины")]
public SupportedPluginsConfig supportedPluginsConfig {
get;
set;
}
public static PluginConfig DefaultConfig() {
return new PluginConfig() {
version = "1.2.8", prefix = "[JetPack]", permissionForUse = "jetpack.use", permissionJetpackCommand = "jetpack.command", permissionForGiveSelf = "jetpack.giveself", permissionForNoFuel = "jetpack.fuel", wearWhenItemAdded = false, allowOpenFromAnyContainer = false, maxHeight = 1000, isWeaponAllowed = true, isTakeOffJetInWater = true, isAirTakeOffAllowed = false, isAirEquipfAllowed = false, isThirdPersonView = false, isSoundEnabled = true, isQuiteSound = false, isFallDamageEnabled = true, fallDamageMultiplicator = 5f, fallDamagePoint = 2.5f, isPlayerSamsWiillAttack = true, isSamsRadiusAndSpeedIncreased = true, homingLauncherConfig = new HomingLauncherConfig {
isEnable = true, targetCaptureDistance = 1
}
, blockedCommands = new HashSet<string> {
"home"
}
, control = new ControlConfig {
force = 20f, cren = 1.5f, upDown = 1.5f, yaw = 1.5f, drag = 0.7f, autoCrenHold = true,
}
, fuel = new FuelConfig {
fuel = true, periodFuel = 1, fuelPerTick = 1, itemShortname = "lowgradefuel",
}
, itemConfig = new ItemConfig {
shortname = "burlap.gloves.new", skin = 2632956407, name = "Jetpack"
}
, isSpawnInLootEnabled = false, crates = new List<CrateConfig> {
new CrateConfig {
Prefab = "assets/bundled/prefabs/radtown/crate_elite.prefab", Chance = 5f
}
}
, notificationConfig = new NotificationConfig {
isChat = true,
}
, supportedPluginsConfig = new SupportedPluginsConfig {
zoneManager = new ZoneManagerConfig {
enable = false, blockFlags = new HashSet<string> {
"eject", "pvegod"
}
, blockIDs = new HashSet<string> {
"Example"
}
}
}
}
;
}
// ... [Code preview truncated due to length. Full source in attached file] ...