C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Mini-Copter Options", "Pho3niX90", "2.0.31")]
[Description("Provide a number of additional options for Mini-Copters, including storage and seats.")]
class MiniCopterOptions : RustPlugin
{
static MiniCopterOptions _instance;
bool lastRanAtNight;
RaycastHit raycastHit;
#region Prefab Modifications
private readonly string storagePrefab = "assets/prefabs/deployable/hot air balloon/subents/hab_storage.prefab";
private readonly string storageLargePrefab = "assets/content/vehicles/boats/rhib/subents/rhib_storage.prefab";
private readonly string autoturretPrefab = "assets/prefabs/npc/autoturret/autoturret_deployed.prefab";
private readonly string switchPrefab = "assets/prefabs/deployable/playerioents/simpleswitch/switch.prefab";
private readonly string searchLightPrefab = "assets/prefabs/deployable/search light/searchlight.deployed.prefab";
private readonly string batteryPrefab = "assets/prefabs/deployable/playerioents/batteries/smallrechargablebattery.deployed.prefab";
private readonly string flasherBluePrefab = "assets/prefabs/deployable/playerioents/lights/flasherlight/electric.flasherlight.deployed.prefab";
private readonly string flasherRedPrefab = "assets/prefabs/deployable/playerioents/lights/sirenlight/electric.sirenlight.deployed.prefab";
private readonly string strobePrefab = "assets/content/props/strobe light/strobelight.prefab";
private readonly string lockPrefab = "assets/prefabs/locks/keypad/lock.code.prefab";
private readonly string spherePrefab = "assets/prefabs/visualization/sphere.prefab";
private readonly string fxBoatPush = "assets/content/vehicles/boats/effects/small-boat-push-land.prefab";
TOD_Sky time;
float sunrise;
float sunset;
float lastCheck;
void Loaded() {
_instance = this;
if (config.lightTail) {
time = TOD_Sky.Instance;
sunrise = time.SunriseTime;
sunset = time.SunsetTime;
time.Components.Time.OnHour += OnHour;
}
}
void Unload() {
foreach (var copter in UnityEngine.Object.FindObjectsOfType<MiniCopter>()) {
RestoreMiniCopter(copter, config.reloadStorage);
if (config.landOnCargo) UnityEngine.Object.Destroy(copter.GetComponent<MiniShipLandingGear>());
}
if (config.lightTail) {
time.Components.Time.OnHour -= OnHour;
}
}
void OnHour() {
float hour = time.Cycle.Hour;
bool isNight = !(hour >= sunrise && hour <= sunset);
//Puts($"OnHour: hour is now {hour}, and it is night {isNight}");
if ((isNight == lastRanAtNight) || (lastCheck == hour)) return;
//Puts($"OnHour Called: Night:{isNight} LastRanAtNight:{lastRanAtNight}");
lastCheck = hour;
MiniCopter[] minis = BaseNetworkable.FindObjectsOfType<MiniCopter>().Where(x => x.GetComponentInChildren<FlasherLight>() != null).ToArray();
//Puts($"OnHour Called: Minis to modify {minis.Count()}");
foreach (var mini in minis) {
ToggleLight(mini.GetComponentInChildren<FlasherLight>());
}
lastRanAtNight ^= true;
}
void OnPlayerInput(BasePlayer player, InputState input) {
if (!config.addSearchLight || player == null || input == null) return;
if (player.isMounted) {
BaseVehicle vehicle = player.GetMountedVehicle();
if (vehicle != null && vehicle is MiniCopter && input.WasJustPressed(BUTTON.USE)) {
ToggleMiniLights(vehicle as MiniCopter);
}
} else if (input.WasJustPressed(BUTTON.RELOAD) && player.GetActiveItem() == null && !player.isMounted) {
GetTargetEntity(player);
}
}
void ToggleMiniLights(MiniCopter mini) {
foreach (var light in mini.GetComponentsInChildren<SearchLight>()) {
ToggleFLight(light);
}
}
void OnEntityDismounted(BaseMountable entity, BasePlayer player) {
if (config.flyHackPause > 0 && entity is MiniCopter)
player.PauseFlyHackDetection(config.flyHackPause);
}
object CanMountEntity(BasePlayer player, BaseMountable entity) {
if (!(entity is MiniCopter) && !(entity.GetParentEntity() is MiniCopter)) return null;
if (player.serverInput.IsDown(BUTTON.FIRE_PRIMARY) || player.serverInput.WasDown(BUTTON.FIRE_PRIMARY)) {
GetTargetEntity(player);
return false;
}
if (!IsBatEnabled()) return null;
MiniCopter ent = entity.GetParentEntity() as MiniCopter;
if (ent != null) {
IOEntity ioe = GetBatteryConnected(ent);
if (ioe != null) {
SendReply(player, GetMsg("Err - Diconnect Battery"), ioe.GetDisplayName());
return false;
}
}
return null;
}
void AddLargeStorageBox(MiniCopter copter) {
//sides,negative left | up and down | in and out
if (config.storageLargeContainers == 1) {
AddStorageBox(copter, storageLargePrefab, new Vector3(0.0f, 0.07f, -1.05f), Quaternion.Euler(0, 180f, 0));
} else if (config.storageLargeContainers >= 2) {
AddStorageBox(copter, storageLargePrefab, new Vector3(-0.48f, 0.07f, -1.05f), Quaternion.Euler(0, 180f, 0));
AddStorageBox(copter, storageLargePrefab, new Vector3(0.48f, 0.07f, -1.05f), Quaternion.Euler(0, 180f, 0));
}
}
void AddRearStorageBox(MiniCopter copter) {
AddStorageBox(copter, storagePrefab, new Vector3(0, 0.75f, -1f));
}
void AddSideStorageBoxes(MiniCopter copter) {
AddStorageBox(copter, storagePrefab, new Vector3(0.6f, 0.24f, -0.35f));
if (!IsBatEnabled()) AddStorageBox(copter, storagePrefab, new Vector3(-0.6f, 0.24f, -0.35f));
}
void AddStorageBox(MiniCopter copter, string prefab, Vector3 position) {
AddStorageBox(copter, prefab, position, new Quaternion());
}
void AddStorageBox(MiniCopter copter, string prefab, Vector3 position, Quaternion q) {
StorageContainer box = GameManager.server.CreateEntity(prefab, copter.transform.position, q) as StorageContainer;
if (prefab.Equals(storageLargePrefab) && config.largeStorageLockable) {
box.isLockable = true;
box.panelName = GetPanelName(config.largeStorageSize);
}
box.Spawn();
box.SetParent(copter);
box.transform.localPosition = position;
if (prefab.Equals(storageLargePrefab) && config.largeStorageLockable) {
box.inventory.capacity = config.largeStorageSize;
}
box.SendNetworkUpdateImmediate(true);
}
void AddFlightLigts(MiniCopter copter) {
FlasherLight alight = GameManager.server.CreateEntity(flasherBluePrefab, copter.transform.position) as FlasherLight;
alight.Spawn();
DestroyGroundComp(alight);
ToggleLight(alight);
alight.SetParent(copter);
alight.transform.localPosition = new Vector3(0, 1.2f, -2.0f);
alight.transform.localRotation = Quaternion.Euler(new Vector3(33, 180, 0));
alight.SendNetworkUpdateImmediate();
}
void ToggleLight(IOEntity ent) {
ent.UpdateHasPower(!ent.IsPowered() ? 10 : 0, 1);
ent.SetFlag(BaseEntity.Flags.On, !ent.IsPowered());
ent.SendNetworkUpdateImmediate();
}
void ToggleFLight(BaseEntity ent) {
ent.SetFlag(BaseEntity.Flags.On, !ent.IsOn());
if (ent is SearchLight) {
SearchLight sl = ent as SearchLight;
sl.secondsRemaining = 9999999999;
}
ent.SendNetworkUpdateImmediate();
}
void AddSearchLight(MiniCopter copter) {
SphereEntity sph = (SphereEntity)GameManager.server.CreateEntity(spherePrefab, copter.transform.position, new Quaternion(0, 0, 0, 0), true);
DestroyMeshCollider(sph);
DestroyGroundComp(sph);
sph.Spawn();
sph.SetParent(copter);
sph.transform.localPosition = new Vector3(0, -100, 0);
SearchLight searchLight = GameManager.server.CreateEntity(searchLightPrefab, sph.transform.position) as SearchLight;
DestroyMeshCollider(searchLight);
DestroyGroundComp(searchLight);
searchLight.Spawn();
searchLight.GetComponent<StorageContainer>().isLootable = false;
searchLight.SetFlag(BaseEntity.Flags.Reserved5, true, false, true);
searchLight.SetParent(sph);
searchLight.transform.localPosition = new Vector3(0, 0, 0);
searchLight.transform.localRotation = Quaternion.Euler(new Vector3(20, 0, 180));
searchLight.transform.localRotation = Quaternion.Euler(new Vector3(20, 0, 0));
searchLight.transform.localRotation = Quaternion.Euler(new Vector3(20, 0, 180));
Puts(searchLight.eyePoint.transform.position.ToString());
searchLight._maxHealth = 99999999f;
searchLight._health = 99999999f;
searchLight.pickup.enabled = false;
searchLight.isLockable = true;
searchLight.SendNetworkUpdate();
sph.transform.localScale += new Vector3(0.9f, 0, 0);
sph.LerpRadiusTo(0.1f, 10f);
timer.Once(3f, () => {
sph.transform.localPosition = new Vector3(0, 0.24f, 1.8f);
});
sph.SendNetworkUpdateImmediate();
//PrintComponents(searchLight);
}
void AddLock(BaseEntity ent) {
CodeLock alock = GameManager.server.CreateEntity(lockPrefab) as CodeLock;
alock.Spawn();
alock.code = "789456789123";
alock.SetParent(ent, ent.GetSlotAnchorName(BaseEntity.Slot.Lock));
alock.transform.localScale += new Vector3(-50, -50, -50);
ent.SetSlot(BaseEntity.Slot.Lock, alock);
alock.SetFlag(BaseEntity.Flags.Locked, true);
alock.SendNetworkUpdateImmediate();
}
void AddTurret(MiniCopter copter) {
AutoTurret aturret = GameManager.server.CreateEntity(autoturretPrefab, copter.transform.position) as AutoTurret;
DestroyMeshCollider(aturret);
DestroyGroundComp(aturret);
aturret.Spawn();
aturret.pickup.enabled = false;
aturret.sightRange = config.turretRange;
aturret.SetParent(copter);
aturret.transform.localPosition = new Vector3(0, 0, 2.47f);
aturret.transform.localRotation = Quaternion.Euler(0, 0, 0);
ProtoBuf.PlayerNameID pnid = new ProtoBuf.PlayerNameID();
BasePlayer player = BasePlayer.FindByID(copter.OwnerID);
if (player != null) {
pnid.userid = player.userID;
pnid.username = player?.displayName;
aturret.authorizedPlayers.Add(pnid);
}
aturret.SendNetworkUpdate();
AddSwitch(aturret);
}
bool IsBatEnabled() => config.autoturretBattery && config.autoturret;
ElectricBattery AddBattery(MiniCopter copter) {
ElectricBattery abat = GameManager.server.CreateEntity(batteryPrefab, copter.transform.position) as ElectricBattery;
abat.maxOutput = 12;
abat.Spawn();
DestroyGroundComp(abat);
abat.pickup.enabled = false;
abat.SetParent(copter);
abat.transform.localPosition = new Vector3(-0.7f, 0.2f, -0.2f);
abat.transform.localRotation = Quaternion.Euler(0, 0, 0);
abat.SendNetworkUpdate();
return abat;
}
void AddSwitch(AutoTurret aturret) {
ElectricBattery bat = null;
if (IsBatEnabled()) {
bat = AddBattery(aturret.GetParentEntity() as MiniCopter);
}
ElectricSwitch aSwitch = aturret.GetComponentInChildren<ElectricSwitch>();
aSwitch = GameManager.server.CreateEntity(switchPrefab, aturret.transform.position)?.GetComponent<ElectricSwitch>();
if (aSwitch == null) return;
aSwitch.pickup.enabled = false;
aSwitch.SetParent(aturret);
aSwitch.transform.localPosition = new Vector3(0f, -0.65f, 0.325f);
aSwitch.transform.localRotation = Quaternion.Euler(0, 0, 0);
DestroyMeshCollider(aSwitch);
DestroyGroundComp(aSwitch);
aSwitch.Spawn();
aSwitch._limitedNetworking = false;
if (!IsBatEnabled()) {
RunWire(aSwitch, 0, aturret, 0, 12);
} else if (bat != null) {
RunWire(bat, 0, aSwitch, 0);
RunWire(aSwitch, 0, aturret, 0);
}
}
// https://umod.org/community/rust/12554-trouble-spawning-a-switch?page=1#post-5
private void RunWire(IOEntity source, int s_slot, IOEntity destination, int d_slot, int power = 0) {
destination.inputs[d_slot].connectedTo.Set(source);
destination.inputs[d_slot].connectedToSlot = s_slot;
destination.inputs[d_slot].connectedTo.Init();
source.outputs[s_slot].connectedTo.Set(destination);
source.outputs[s_slot].connectedToSlot = d_slot;
source.outputs[s_slot].connectedTo.Init();
source.MarkDirtyForceUpdateOutputs();
if (power > 0) {
destination.UpdateHasPower(power, 0);
source.UpdateHasPower(power, 0);
}
source.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
destination.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
}
void DestroyGroundComp(BaseEntity ent) {
UnityEngine.Object.DestroyImmediate(ent.GetComponent<DestroyOnGroundMissing>());
UnityEngine.Object.DestroyImmediate(ent.GetComponent<GroundWatch>());
}
void DestroyMeshCollider(BaseEntity ent) {
foreach (var mesh in ent.GetComponentsInChildren<MeshCollider>()) {
UnityEngine.Object.DestroyImmediate(mesh);
}
}
IOEntity GetBatteryConnected(MiniCopter ent) {
return ent.GetComponentInChildren<ElectricBattery>()?.inputs[0]?.connectedTo.ioEnt;
}
private object OnSwitchToggle(ElectricSwitch eswitch, BasePlayer player) {
if (IsBatEnabled()) return null;
BaseEntity parent = eswitch.GetParentEntity();
if (parent != null && parent.PrefabName.Equals(autoturretPrefab)) {
AutoTurret turret = parent as AutoTurret;
if (turret == null) return null;
if (!eswitch.IsOn())
PowerTurretOn(turret);
else
PowerTurretOff(turret);
}
return null;
}
public void PowerTurretOn(AutoTurret turret) {
turret.SetFlag(BaseEntity.Flags.Reserved8, true);
turret.InitiateStartup();
}
private void PowerTurretOff(AutoTurret turret) {
turret.SetFlag(BaseEntity.Flags.Reserved8, false);
turret.InitiateShutdown();
}
string GetPanelName(int capacity) {
if (capacity <= 6) {
return "smallstash";
} else if (capacity > 6 && capacity <= 12) {
return "smallwoodbox";
} else if (capacity > 12 && capacity <= 30) {
return "largewoodbox";
} else {
return "genericlarge";
}
}
void RestoreMiniCopter(MiniCopter copter, bool removeStorage = false) {
copter.fuelPerSec = copterDefaults.fuelPerSecond;
copter.liftFraction = copterDefaults.liftFraction;
copter.torqueScale = copterDefaults.torqueScale;
if (removeStorage) {
foreach (var child in copter.children) {
if (child.name == storagePrefab || child.name == storageLargePrefab || child.name == autoturretPrefab) {
copter.RemoveChild(child);
child.Kill();
}
}
}
}
void ModifyMiniCopter(MiniCopter copter, bool storage = false) {
copter.fuelPerSec = config.fuelPerSec;
copter.liftFraction = config.liftFraction;
copter.torqueScale = new Vector3(config.torqueScalePitch, config.torqueScaleYaw, config.torqueScaleRoll);
if (config.autoturret && copter.GetComponentInChildren<AutoTurret>() == null) {
timer.Once(copter.isSpawned ? 0 : 0.2f, () => {
AddTurret(copter);
});
}
if (storage) AddLargeStorageBox(copter);
if (storage)
switch (config.storageContainers) {
case 1:
AddRearStorageBox(copter);
break;
case 2:
AddSideStorageBoxes(copter);
break;
case 3:
AddRearStorageBox(copter);
AddSideStorageBoxes(copter);
break;
}
}
void StoreMiniCopterDefaults(MiniCopter copter) {
if (copter.liftFraction == 0 || copter.torqueScale.x == 0 || copter.torqueScale.y == 0 || copter.torqueScale.z == 0) {
copter.liftFraction = 0.25f;
copter.torqueScale = new Vector3(400f, 400f, 200f);
}
Puts($"Defaults for copters saved as \nfuelPerSecond = {copter.fuelPerSec}\nliftFraction = {copter.liftFraction}\ntorqueScale = {copter.torqueScale}");
copterDefaults = new MiniCopterDefaults {
fuelPerSecond = copter.fuelPerSec,
liftFraction = copter.liftFraction,
torqueScale = copter.torqueScale
};
}
#endregion
#region Hooks
void OnItemDeployed(Deployer deployer, BaseEntity entity) {
if (entity?.GetParentEntity() != null && (entity.GetParentEntity() is MiniCopter)) {
CodeLock cLock = entity.GetComponentInChildren<CodeLock>();
cLock.transform.localPosition = new Vector3(0.0f, 0.3f, 0.298f);
cLock.transform.localRotation = Quaternion.Euler(new Vector3(0, 90, 0));
cLock.SendNetworkUpdateImmediate();
}
}
void OnServerInitialized() {
PrintWarning("Applying settings except storage modifications to existing MiniCopters.");
foreach (var copter in UnityEngine.Object.FindObjectsOfType<MiniCopter>()) {
// Nab the default values off the first minicopter.if (copterDefaults.Equals(default(MiniCopterDefaults))) {
StoreMiniCopterDefaults(copter);
break;
}
if (config.landOnCargo) copter.gameObject.AddComponent<MiniShipLandingGear>();
ModifyMiniCopter(copter, config.reloadStorage);
}
}
void OnEntitySpawned(MiniCopter mini) {
//PrintComponents(mini);
if (mini.name.Contains("trans")) return;
// Only add storage on spawn so we don't stack or mess with
// existing player storage containers.ModifyMiniCopter(mini, true);
if (config.landOnCargo) mini.gameObject.AddComponent<MiniShipLandingGear>();
if (config.addSearchLight) AddSearchLight(mini);
if (config.lightTail) AddFlightLigts(mini);
}
void OnEntityKill(BaseNetworkable entity) {
if (!config.dropStorage || !(entity is MiniCopter)) return;
StorageContainer[] containers = entity.GetComponentsInChildren<StorageContainer>();
foreach (StorageContainer container in containers) {
container.DropItems();
}
AutoTurret[] turrets = entity.GetComponentsInChildren<AutoTurret>();
foreach (AutoTurret turret in turrets) {
turret.DropItems();
}
}
#endregion
#region Configuration
private class MiniCopterOptionsConfig
{
// Populated with Rust defaults.public float fuelPerSec = 0.25f;
public float liftFraction = 0.25f;
public float torqueScalePitch = 400f;
public float torqueScaleYaw = 400f;
public float torqueScaleRoll = 200f;
public int storageContainers = 0;
public int storageLargeContainers = 0;
public bool restoreDefaults = true;
public bool reloadStorage = false;
public bool dropStorage = true;
public bool largeStorageLockable = true;
public int largeStorageSize = 42;
public int flyHackPause = 1;
public bool autoturret = false;
public bool landOnCargo = true;
public bool allowMiniPush = true;
public bool autoturretBattery = true;
public bool addSearchLight = true;
public float turretRange = 30f;
public bool lightTail = false;
// Plugin reference
private MiniCopterOptions plugin;
public MiniCopterOptionsConfig(MiniCopterOptions plugin) {
this.plugin = plugin;
GetConfig(ref fuelPerSec, "Fuel per Second");
GetConfig(ref liftFraction, "Lift Fraction");
GetConfig(ref torqueScalePitch, "Pitch Torque Scale");
GetConfig(ref torqueScaleYaw, "Yaw Torque Scale");
GetConfig(ref torqueScaleRoll, "Roll Torque Scale");
GetConfig(ref storageContainers, "Storage Containers");
GetConfig(ref storageLargeContainers, "Large Storage Containers");
GetConfig(ref restoreDefaults, "Restore Defaults");
GetConfig(ref reloadStorage, "Reload Storage");
GetConfig(ref dropStorage, "Drop Storage Loot On Death");
GetConfig(ref largeStorageLockable, "Large Storage Lockable");
GetConfig(ref largeStorageSize, "Large Storage Size (Max 42)");
GetConfig(ref flyHackPause, "Seconds to pause flyhack when dismount from heli.");
GetConfig(ref autoturret, "Add auto turret to heli");
GetConfig(ref autoturretBattery, "Auto turret uses battery");
GetConfig(ref landOnCargo, "Allow Minis to Land on Cargo");
GetConfig(ref turretRange, "Mini Turret Range (Default 30)");
GetConfig(ref allowMiniPush, "Allow minicopter push");
GetConfig(ref addSearchLight, "Light: Add Searchlight to heli");
GetConfig(ref lightTail, "Light: Add Nightitme Tail Light");
plugin.SaveConfig();
}
private void GetConfig<T>(ref T variable, params string[] path) {
if (path.Length == 0) return;
if (plugin.Config.Get(path) == null) {
SetConfig(ref variable, path);
plugin.PrintWarning($"Added field to config: {string.Join("/", path)}");
}
variable = (T)Convert.ChangeType(plugin.Config.Get(path), typeof(T));
}
private void SetConfig<T>(ref T variable, params string[] path) => plugin.Config.Set(path.Concat(new object[] { variable }).ToArray());
}
protected override void LoadDefaultConfig() => PrintWarning("Generating new configuration file.");
private MiniCopterOptionsConfig config;
struct MiniCopterDefaults
{
public float fuelPerSecond;
public float liftFraction;
public Vector3 torqueScale;
}
MiniCopterDefaults copterDefaults;
private void Init() {
config = new MiniCopterOptionsConfig(this);
if (config.storageContainers > 3) {
PrintWarning($"Storage Containers configuration value {config.storageContainers} exceeds the maximum, setting to 3.");
config.storageContainers = 3;
} else if (config.storageContainers < 0) {
PrintWarning($"Storage Containers cannot be a negative value, setting to 0.");
config.storageContainers = 0;
}
if (config.storageLargeContainers > 2) {
PrintWarning($"Large Storage Containers configuration value {config.storageLargeContainers} exceeds the maximum, setting to 2.");
config.storageLargeContainers = 2;
} else if (config.storageLargeContainers < 0) {
PrintWarning($"Large Storage Containers cannot be a negative value, setting to 0.");
config.storageLargeContainers = 0;
}
if (config.largeStorageSize > 42) {
PrintWarning($"Large Storage Containers Capacity configuration value {config.largeStorageSize} exceeds the maximum, setting to 42.");
config.largeStorageSize = 42;
} else if (config.largeStorageSize < 6) {
PrintWarning($"Storage Containers Capacity cannot be a smaller than 6, setting to 6.");
}
}
#endregion
#region Chat Commands
[ChatCommand("push")]
private void PushMiniChatCommand(BasePlayer player, string command, string[] args) {
if (!config.allowMiniPush) return;
GetTargetEntity(player);
}
#endregion
#region Helpers
private void GetTargetEntity(BasePlayer player) {
bool flag = Physics.Raycast(player.eyes.HeadRay(), out raycastHit, 2f, Rust.Layers.Solid);
if (!flag) return;
BaseEntity entity;
try {
entity = raycastHit.GetEntity();
} catch (NullReferenceException nre) {
return;
}
if (entity == null) return;
MiniCopter mini = ((entity is MiniCopter) ? entity : entity.GetParentEntity()) as MiniCopter;
if (mini != null) {
PushMini(player, mini);
return;
}
SendReply(player, GetMsg("Err - Can only push minicopter"), GetEnglishName(entity.ShortPrefabName));
}
private string GetEnglishName(string shortName) { return ItemManager.FindItemDefinition(shortName)?.displayName?.english ?? shortName; }
void PushMini(BasePlayer player, BaseVehicle bVehicle) {
//bVehicle.rigidBody.AddForceAtPosition(Vector3.up * 15f, raycastHit.point, ForceMode.VelocityChange);
bVehicle.rigidBody.AddForceAtPosition(Vector3.up * 3.0f, raycastHit.point, ForceMode.VelocityChange);
//bVehicle.rigidBody.AddForceAtPosition(Vector3.forward * 5.5f, raycastHit.point, ForceMode.VelocityChange);
timer.Once(0.1f, () => {
bVehicle.rigidBody.AddForceAtPosition(Vector3.forward * 1f, raycastHit.point, ForceMode.VelocityChange);
});
player.metabolism.calories.Subtract(2f);
player.metabolism.SendChangesToClient();
Effect.server.Run(fxBoatPush, bVehicle.GetNetworkPosition());
}
void PrintComponents(BaseEntity ent) {
foreach (var sl in ent.GetComponents<Component>()) {
Puts($"-P- {sl.GetType().Name} | {sl.name}");
foreach (var s in sl.GetComponentsInChildren<Component>()) {
Puts($"-C- {s.GetType().Name} | {s.name}");
}
}
}
#endregion
#region Classes
public class MiniShipLandingGear : MonoBehaviour
{
private MiniCopter miniCopter;
private bool pCargo;
void Awake() {
miniCopter = GetComponent<MiniCopter>();
}
void OnTriggerEnter(Collider collider) {
if (!collider.isTrigger || !(collider.ToBaseEntity() is CargoShip) || pCargo) return;
ParentTo(miniCopter, collider.ToBaseEntity());
}
void OnTriggerExit(Collider collider) {
if (!collider.isTrigger || !(collider.ToBaseEntity() is CargoShip) || !pCargo) return;
ParentTo(miniCopter, null);
}
void ParentTo(MiniCopter mini, BaseEntity parent) {
mini.SetParent(parent, true);
pCargo ^= true;
}
}
#endregion
#region Languages
protected override void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["Err - Diconnect Battery"] = "First disconnect battery input from {0}",
["Err - Can only push minicopter"] = "You have to look at a minicopter.Pushing {0} not allowed"
}, this);
}
string GetMsg(string key, object userID = null) => lang.GetMessage(key, this, userID == null ? null : userID.ToString());
#endregion
}
}