C#:
using System.Collections.Generic;
using Physics = UnityEngine.Physics;
using VLB;
using Oxide.Core.Plugins;
using System;
using UnityEngine;
using Color = UnityEngine.Color;
using Newtonsoft.Json;
using ConVar;
using System.Drawing;
using Oxide.Core.Libraries.Covalence;
using Oxide.Game.Rust.Cui;
using Time = UnityEngine.Time;
using Oxide.Core;
using System.Linq;
using Rust;
namespace Oxide.Plugins {
[Info("Teleportation", "BadMandarin", "1.1.5")]
[Description("Teleportation")]
class Teleportation : RustPlugin {
public class SettingsTemperature {
[JsonProperty("Минимальное кол-во температуры, для отмены тп [Minimum temperature, for canceling TP]")]
public float MinNeedTemperature = 3f;
[JsonProperty("Запретить телепортацию при низкой температуре? [Prohibit teleportation at low temperatures?]")]
public bool CantTeleportTemperature = true;
}
public class SettingsHome {
[JsonProperty("Время на телепортацию ('Пермишен': Секунд) [Teleportation Time('Permission': seconds)]", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, float> TeleportationTime = new Dictionary<string, float>() {
["teleportation.default"]
= 10f
}
;
[JsonProperty("Учитывать дистанцию при телепортации? [Take into account the distance?]")]
public bool ConsiderDistance = false;
[JsonProperty("КД на телепортацию('Пермишен': Секунд) [Cooldown Teleportation('Permission': seconds)]", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, float> CooldownTeleportation = new Dictionary<string, float>() {
["teleportation.default"]
= 30f
}
;
[JsonProperty("Количество домов['Пермишен': Количество] [Count Home ('Permission': seconds)]", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, int> CountHome = new Dictionary<string, int>() {
["teleportation.default"]
= 3
}
;
[JsonProperty("Множитель телепортации(для дистанции) [Multiplier teleportation for distance]")]
public double Multiplier = 10;
[JsonProperty("Проверять фундамент на владельца? [Check foundation for owner?]")]
public bool CheckFoundationForOwner = true;
[JsonProperty("Список разрешенных для установки дома блоков [Valid building blocks for home]", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public string[] AvailableFoundations = new [] {
"assets/prefabs/building core/foundation/foundation.prefab", "assets/prefabs/building core/foundation.triangle/foundation.triangle.prefab"
}
;
[JsonProperty("Включить систему спальников? [Enable sleeping bag system?]")]
public bool EnableSleepingBags = true;
}
void Unload() {
PluginData.SaveData();
for (var i = 0; i < MarkerBag.MarkerBags.Count; i++) UnityEngine.Object.Destroy(MarkerBag.MarkerBags[i]);
for (var i = 0; i < TeleportMgr.ManagersList.Count; i++) UnityEngine.Object.Destroy(TeleportMgr.ManagersList[i]);
for (var i = 0; i < _config.SettingsMonument.AvailableMonuments.Count; i++) {
var monument = _config.SettingsMonument.AvailableMonuments[i];
if(monument.CreatedBag != null) monument.CreatedBag.Kill();
}
}
private int GetHomeLimit(ulong uid) {
int max = -1;
foreach (var privilege in _config.SettingsHome.CountHome) if (permission.UserHasPermission(uid.ToString(), privilege.Key)) max = Mathf.Max(max, privilege.Value);
return max;
}
private static string GetColor(string hex, float alpha = 1f) {
if (hex.Length != 7) hex = "#FFFFFF";
if (alpha < 0 || alpha > 1f) alpha = 1f;
var color = ColorTranslator.FromHtml(hex);
var r = Convert.ToInt16(color.R) / 255f;
var g = Convert.ToInt16(color.G) / 255f;
var b = Convert.ToInt16(color.B) / 255f;
return $"{r} {g} {b} {alpha}";
}
private void CheckStatus() {
int loadedImages = 0;
foreach (var value in _imagesLoading) {
if (HasImage(value) == false) continue;
loadedImages++;
}
if (loadedImages < _imagesLoading.Count - 1 && (bool)ImageLibrary.Call("IsReady") == false) {
PrintError($"Plugin is not ready! Loaded: {loadedImages}/{_imagesLoading.Count} images.");
timer.Once(10f, CheckStatus);
}
else {
FullLoad();
PrintWarning("Plugin succesfully loaded! Author: BadMandarin.");
}
}
[ChatCommand("sethome")]
private void ChatCommandSetHome(BasePlayer player, string command, string[] args) {
if (GetHomeLimit(player.userID) <= 0) return;
var foundationList = GetFoundation(player.ServerPosition);
if (foundationList == null || foundationList.Count == 0) {
SendMessage(player, "FOUNDATION.NOT.FOUND");
return;
}
var foundation = foundationList?.First();
if (foundation == null) {
SendMessage(player, "FOUNDATION.NOT.FOUND");
return;
}
string err = CheckFoundation(player.userID, player.ServerPosition);
if (err != null) {
SendMessage(player, err);
return;
}
err = CheckInsideBlock(player.ServerPosition);
if (err != null) {
SendMessage(player, err);
return;
}
if (player.GetBuildingPrivilege(player.WorldSpaceBounds()) != null && !player.GetBuildingPrivilege(player.WorldSpaceBounds()).authorizedPlayers.Select(p => p.userid).Contains(player.userID)) {
Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
SendMessage(player, "SETHOME.CANCEL.BUILD");
return;
}
if (args.Length != 1) {
SendMessage(player, "SETHOME.HELP");
return;
}
if (player.IsWounded() && _config.SettingsResolution.CantTeleportWounded || player.metabolism.bleeding.value > _config.SettingsResolution.SettingsBleeding.NeedBleedingAmount && _config.SettingsResolution.SettingsBleeding.CantTeleportBleeding) {
SendMessage(player, "BLOOD.OR.WOUNDED");
return;
}
SetHome(player, args[0]);
}
[ConsoleCommand("home")]
void ConsoleCmdHome(ConsoleSystem.Arg arg) {
var player = arg.Player();
if (player == null) return;
if (arg.HasArgs() == false) return;
ChatCommandHome(player, "", arg.Args);
}
private MonumentInfo FindClosestMonument(Vector3 position) {
MonumentInfo info = null;
float minDistance = float.MaxValue;
var monuments = TerrainMeta.Path.Monuments;
foreach (var monument in monuments) {
float distance = Vector3.Distance(position, monument.transform.position);
if (distance > minDistance) continue;
minDistance = distance;
info = monument;
}
return info;
}
[ChatCommand("tpr")]
private void ChatCommandTpr(BasePlayer player, string command, string[] args) {
if (GetTeleportTimeTpr(player.userID) <= 0) return;
if (args.Length < 1) {
Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
SendMessage(player, "TPR.HELP");
return;
}
var ret = Interface.Call("CanTeleport", player) as string;
if (ret != null) {
SendMessageWithoutLang(player, ret);
return;
}
var message = CanTeleportPlayer(player);
if (string.IsNullOrEmpty(message) == false) {
Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
SendMessageWithoutLang(player, message);
return;
}
var data = PluginData.GetForPlayer(player.userID);
if (data == null) return;
if (data.CooldownTeleport >= GetCurrentTime()) {
SendMessage(player, "TPR.COOLDOWN", TimeHelper.FormatTime(TimeSpan.FromSeconds(data.CooldownTeleport - GetCurrentTime()), language : lang.GetLanguage(player.UserIDString)));
return;
}
BasePlayer target = null;
if(!PlayerHelper.FindOnlineMultiple(string.Join(" ", args), player, out target)) {
return;
}
if (target == null) return;
if (target == player) return;
var teleportMgr = TeleportMgr.GetManager(player);
if (teleportMgr == null) return;
if (teleportMgr.HasRequest()) {
SendMessage(player, "TPR.PLAYER.CANCEL.REQUEST");
return;
}
var targetTeleportMgr = TeleportMgr.GetManager(target);
if (targetTeleportMgr == null) return;
teleportMgr.InitRequest(target.transform.position, false, target);
targetTeleportMgr.IncomingRequests.Add(teleportMgr.Request);
SendMessage(player, "TPR.PLAYER.SEND", target.displayName);
SendMessage(target, "TPR.TARGET.SEND", player.displayName);
var targetData = PluginData.GetForPlayer(target.userID);
if (targetData?.AutoAccept == true && IsFriend(player.userID, target.userID)) {
ChatCommandTpa(target, "", new string[] {
""
}
);
return;
}
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiPanel {
CursorEnabled = false, RectTransform = {
AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMax = "0 0"
}
, Image = {
Color = GetColor("#FFFFFF", 0.4f)
}
}
, "Hud", LayerNotification);
container.Add(new CuiElement() {
Parent = LayerNotification, Name = LayerNotification + ".Main", Components = {
new CuiRawImageComponent() {
Png = GetImage(TeleportImage)
}
, new CuiRectTransformComponent() {
AnchorMin = $"0 0", AnchorMax = $"1 1", OffsetMin = "-200 81", OffsetMax = "180 117.6"
}
,
}
}
);
container.Add(new CuiPanel() {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "-151 81", OffsetMax = "132 117.6"
}
, Image = {
Color = "0.9686275 0.9215686 0.8823529 0.13529412"
}
}
, LayerNotification);
container.Add(new CuiLabel() {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "-151 81", OffsetMax = "132 117.6"
}
, Text = {
Text = GetMessage(player, "TPR.UI.REQUEST" , player.displayName), Font = "RobotoCondensed-Bold.ttf", Align = TextAnchor.MiddleCenter, FontSize = 16, Color = GetColor("#FFFFFFB2")
}
,
}
, LayerNotification);
container.Add(new CuiButton() {
RectTransform = {
AnchorMin = "0.02 0", AnchorMax = "0 1", OffsetMax = "49 0"
}
, Button = {
Color = "0 0 0 0", Command = "chat.say /tpc"
}
, Text = {
Text = GetMessage(player, "TPR.UI.REQUEST.NO"), Align = TextAnchor.MiddleCenter, Color = GetColor("#D12C2C"), FontSize = 16
}
}
, LayerNotification + ".Main");
container.Add(new CuiButton() {
RectTransform = {
AnchorMin = "0.98 0", AnchorMax = "1 1", OffsetMin = "-49 0"
}
, Button = {
Color = "0 0 0 0", Command = "chat.say /tpa"
}
, Text = {
Text = GetMessage(player, "TPR.UI.REQUEST.YES"), Align = TextAnchor.MiddleCenter, Color = GetColor("#C1FF9B"), FontSize = 16
}
}
, LayerNotification + ".Main");
CuiHelper.AddUi(target, container);
}
[ChatCommand("tphome")]
private void ChatCommandTpHome(BasePlayer player, string command, string[] args) {
if(player.IsAdmin == false && permission.UserHasPermission(player.UserIDString, AdminPermission) == false) return;
string name = args[0];
BasePlayer target = null;
PlayerData data = null;
switch (args.Length) {
case 1 : if(!PlayerHelper.FindOnlineAndOfflineMultiple(name, player, out target)) {
return;
}
if (target == null) {
Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
SendMessage(player, "PLAYER.NOT.FOUND");
return;
}
data = PluginData.GetForPlayer(target.userID);
if (data == null) break;
if (data.HomesList.Count < 1) {
SendMessage(player, "TP.HOMELIST.ZERO");
return;
}
string homes = "";
for (var i = data.HomesList.Count - 1; i >= 0; i--) {
var home = data.HomesList[i];
homes += $"{home.HomeName}";
if (i != 0) homes += ", ";
}
SendMessage(player, "TP.HOMELIST.FOUND", homes);
break;
case 2 : if(!PlayerHelper.FindOnlineAndOfflineMultiple(name, player, out target)) {
return;
}
if (target == null) {
Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
SendMessage(player, "PLAYER.NOT.FOUND");
return;
}
data = PluginData.GetForPlayer(target.userID);
if (data == null) break;
if (data.HomesList.Count < 1) {
SendMessage(player, "TP.HOMELIST.ZERO");
return;
}
var playerHome = data.HomesList.Find(x => x.HomeName.Contains(string.Join(" ", args.Skip(1))));
if (playerHome == null) break;
Teleport(player, playerHome.HomePos);
break;
case 3 : break;
}
}
[ChatCommand("tpc")]
private void ChatCommandTpc(BasePlayer player, string command, string[] args) {
var teleportMgr = TeleportMgr.GetManager(player);
if (teleportMgr == null) return;
if (teleportMgr.Request != null) {
if (teleportMgr.Request.IsHome) {
teleportMgr.CancelTeleport();
SendMessage(player, "HOME.PLAYER.CANCEL");
return;
}
if (teleportMgr.Request.Monument != null) {
teleportMgr.CancelTeleport();
return;
}
if (teleportMgr.Request.Target != null) {
//var objTarget = TeleportMgr.GetManager(teleportMgr.Request.Target);
SendMessage(teleportMgr.Request.Target, "TPR.TARGET.CANCEL", player.displayName);
//objTarget.CancelTeleport();
}
SendMessage(player, "TPR.PLAYER.CANCEL", teleportMgr.Request.Target.displayName);
teleportMgr.CancelTeleport();
return;
}
var pendingRequest = teleportMgr.IncomingRequests.FirstOrDefault();
if (pendingRequest != null) {
if (pendingRequest.Player != null) {
var objTarget = TeleportMgr.GetManager(pendingRequest.Player);
SendMessage(player, "TPR.PLAYER.CANCEL", pendingRequest.Player.displayName);
SendMessage(pendingRequest.Player, "TPR.TARGET.CANCEL", player.displayName);
objTarget.CancelTeleport();
}
//teleportMgr.IncomingRequests.Remove(pendingRequest);
//teleportMgr.CancelTeleport();
return;
}
}
[ConsoleCommand("tpc")]
void ConsoleCmdTpc(ConsoleSystem.Arg arg) {
var player = arg.Player();
if (player == null) return;
if (arg.HasArgs() == false) return;
ChatCommandTpc(player, "", arg.Args);
}
private class ParentPosition {
public static Vector3 GetFinalPosition(Transform parent, Vector3 offset) {
return parent.TransformPoint(offset);
}
public static Vector3 GetOffsetPosition(Transform parent, Vector3 child) {
return parent.InverseTransformPoint(child);
}
}
[ChatCommand("home")]
private void ChatCommandHome(BasePlayer player, string command, string[] args) {
if (args.Length != 1) {
Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
SendMessage(player, "HOME.HELP");
return;
}
if (GetTeleportTimeHome(player.userID) <= 0) return;
var data = PluginData.GetForPlayer(player.userID);
var homeName = string.Join(" ", args);
var home = data.GetHome(homeName);
if (home == null) {
Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
SendMessage(player, "HOME.NOT.FOUND.OR.REMOVED");
return;
}
var foundationList = GetFoundation(home.HomePos);
if (foundationList == null || foundationList.Count == 0) {
SendMessage(player, "FOUNDATION.NOT.FOUND");
return;
}
var ret = Interface.Call("CanTeleport", player) as string;
if (ret != null) {
SendMessageWithoutLang(player, ret);
return;
}
if (_config.SettingsHome.EnableSleepingBags) {
if (home.SleepingBagId == 0) {
data.HomesList.Remove(home);
Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
SendMessage(player, "HOME.NOT.FOUND.BAG");
return;
}
var bag = BaseNetworkable.serverEntities.Find(new NetworkableId(home.SleepingBagId));
if (bag == null) {
data.HomesList.Remove(home);
Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
SendMessage(player, "HOME.NOT.FOUND.BAG");
return;
}
}
if (data.CooldownHome > GetCurrentTime()) {
Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
SendMessage(player, "HOME.COOLDOWN", TimeHelper.FormatTime(TimeSpan.FromSeconds(data.CooldownHome - GetCurrentTime())));
return;
}
var message = CanTeleportPlayer(player);
if (!string.IsNullOrEmpty(message)) {
Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
SendMessageWithoutLang(player, message);
return;
}
string err = CheckInsideBlock(home.HomePos);
if (err != null) {
SendMessage(player, "HOME.REMOVED.INSIDE.BLOCK", home.HomeName);
data.HomesList.Remove(home);
return;
}
var teleportMgr = TeleportMgr.GetManager(player);
if (teleportMgr == null) return;
if (teleportMgr.HasRequest()) {
SendMessage(player, "TPR.PLAYER.CANCEL.REQUEST");
return;
}
teleportMgr.InitRequest(home.HomePos, true);
SendMessage(player, "HOME.TELEPORTATION", TimeHelper.FormatTime(TimeSpan.FromSeconds(GetTeleportTimeHome(player.userID)), language : lang.GetLanguage(player.UserIDString)));
}
protected override void SaveConfig() {
Config.WriteObject(_config);
}
private const string Layer = "UI.Teleportation";
[ConsoleCommand("tpa")]
void ConsoleCmdTpa(ConsoleSystem.Arg arg) {
var player = arg.Player();
if (player == null) return;
if (arg.HasArgs() == false) return;
ChatCommandTpa(player, "", arg.Args);
}
[ConsoleCommand("tp")]
void ConsoleCmdTp(ConsoleSystem.Arg arg) {
var player = arg.Player();
if (player == null) return;
if (arg.HasArgs() == false) return;
ChatCommandTp(player, "", arg.Args);
}
private static bool _initiated = false;
private readonly int buildingLayer = LayerMask.GetMask("Terrain", "World", "Construction", "Deployed");
private float GetTeleportTimeTpr(ulong uid) {
float min = 9999f;
bool set = false;
foreach (var privilege in _config.SettingsTeleport.TeleportationTime) {
if (permission.UserHasPermission(uid.ToString(), privilege.Key)) {
min = Mathf.Min(min, privilege.Value);
set = true;
}
}
return set ? min : -1f;
}
private class PluginConfig {
[JsonProperty("Автоматически удалять DATA файл при вайпе? [Automatically delete DATA file when wipe?]")]
public bool AutoWipe = true;
[JsonProperty("Использовать плагин друзей? [Use friends plugin?]")]
public bool UseFriends = false;
[JsonProperty("Использовать плагин кланов? [Use clans plugin?]")]
public bool UseClans = false;
[JsonProperty("Использовать систему друзей игры? [Use rust teams system?]")]
public bool UseTeams = true;
[JsonProperty("Настройки дома[SETTINGS HOME]", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public SettingsHome SettingsHome = new SettingsHome();
[JsonProperty("Настройки монументов[SETTINGS MONUMENTs]", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public SettingMonument SettingsMonument = new SettingMonument();
[JsonProperty("Настройки телепортации[SETTINGS TELEPORT]", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public SettingsTeleport SettingsTeleport = new SettingsTeleport();
[JsonProperty("Настройки запретов[SETTINGS RESOLUTION]", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public SettingsResolution SettingsResolution = new SettingsResolution() {
SettingsBleeding = new SettingsBleeding(), SettingsRadiation = new SettingsRadiation(), SettingsTemperature = new SettingsTemperature(),
}
;
}
public class SettingsBleeding {
[JsonProperty("Кол-во кровотечение, при котором будет вызываться запрет на телепортацию [The amount of bleeding that will trigger a ban on teleportation]")]
public float NeedBleedingAmount = 5f;
[JsonProperty("Запретить телепортацию при кровотечении? [Prohibit teleportation during bleeding?]")]
public bool CantTeleportBleeding = true;
}
void OnPlayerConnected(BasePlayer player) {
if (player == null) return;
if (player.HasPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot)) {
timer.Once(2f, () => OnPlayerConnected(player));
return;
}
if (!player.IsConnected) return;
player.GetOrAddComponent<TeleportMgr>();
}
private float GetTeleportCooldownTpr(ulong uid) {
float min = 9999f;
bool set = false;
foreach (var privilege in _config.SettingsTeleport.CooldownTeleportation) {
if (permission.UserHasPermission(uid.ToString(), privilege.Key)) {
min = Mathf.Min(min, privilege.Value);
set = true;
}
}
return set ? min : -1f;
}
private void Teleport(BasePlayer player, BasePlayer target) {
//if (target.GetComponentInParent<Component>() != null ||
// target.GetComponentInParent<HotAirBalloon>() != null || target.GetComponentInParent<Spawnable>() != null || (target.GetParentEntity() != null && target.GetParentEntity().name.Contains("cave")) || (target.GetParentEntity() != null && target.GetParentEntity().name.Contains("junkpile_water")) || (target.GetParentEntity() != null && target.GetParentEntity().name.Contains("cargo")))
if(target.HasParent()) {
player.PauseFlyHackDetection(10f);
player.SetParent(target.GetParentEntity());
player.SendNetworkUpdateImmediate();
}
Teleport(player, target.transform.position, target);
}
public class Request {
public bool IsHome = false;
public SettingMonument.AvailableMonument Monument;
public BasePlayer Target = null;
public BasePlayer Player = null;
public Vector3 Position = Vector3.zero;
public RealTimeSince RequestTimeout = 0;
public bool RequestConfirmed = false;
public Request(BasePlayer player, bool isHome, Vector3 position = default(Vector3), BasePlayer target = null, SettingMonument.AvailableMonument monument = null) {
this.IsHome = isHome;
this.Monument = monument;
this.Target = target;
this.Player = player;
this.Position = position;
}
}
private void StartPluginLoad() {
if (ImageLibrary != null) {
//Load your images here
AddImage(TeleportImage);
CheckStatus();
}
else {
PrintError($"ImageLibrary not found! Please, check your plugins list.");
}
}
[ChatCommand("tp")]
private void ChatCommandTp(BasePlayer player, string command, string[] args) {
if(player.IsAdmin == false && permission.UserHasPermission(player.UserIDString, AdminPermission) == false) return;
switch (args.Length) {
case 0 : break;
case 1 : string name = args[0];
BasePlayer target = null;
if(!PlayerHelper.FindOnlineAndOfflineMultiple(name, player, out target)) {
return;
}
if (target == null) {
Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
SendMessage(player, "PLAYER.NOT.FOUND");
return;
}
Teleport(player, target);
break;
case 2 : string name1 = args[0];
string name2 = args[1];
BasePlayer target1 = null;
if(!PlayerHelper.FindOnlineAndOfflineMultiple(name1, player, out target1)) {
return;
}
BasePlayer target2 = null;
if(!PlayerHelper.FindOnlineAndOfflineMultiple(name2, player, out target2)) {
return;
}
if (target1 == null || target2 == null) {
SendMessage(player, "PLAYER.NOT.FOUND");
return;
}
Teleport(target1, target2);
break;
case 3 : float x = float.Parse(args[0]);
float y = float.Parse(args[1]);
float z = float.Parse(args[2]);
Teleport(player, x, y, z);
break;
}
}
public class SettingsResolution {
[JsonProperty("Запретить телепортацию в воде? [Prohibit teleportation in water?]")]
public bool CantTeleportSwimming = true;
[JsonProperty("Запретить телепортацию, если упал? [Prohibit teleportation if dropped?]")]
public bool CantTeleportWounded = true;
[JsonProperty("Запретить телепортацию, если ползает? [Prohibit teleportation if crawling?]")]
public bool CantTeleportCrawling = true;
[JsonProperty("Запретить телепортацию, если человек находится в билдинг зоне [Prohibit teleportation if a person is in the building zone]")]
public bool CantTeleportInBuild = true;
[JsonProperty("Запретить телепортацию, если человек сидит на обьекте [Prohibit teleportation if a person is mounted]")]
public bool CantTeleportMounted = true;
[JsonProperty("Запретить телепортацию, если человек находиться на движущемся обьекте [Prohibit teleportation if a person is on moving object]")]
public bool CantTeleportParent = true;
[JsonProperty("Запретить телепортацию, если человек находиться в воде [Prohibit teleportation if a person is in water]")]
public bool CantTeleportWater = true;
[JsonProperty("Настройки радиации [Settings Radiation]", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public SettingsRadiation SettingsRadiation = new SettingsRadiation();
[JsonProperty("Настройки кровотечения [Settings Bleeding]", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public SettingsBleeding SettingsBleeding = new SettingsBleeding();
[JsonProperty("Настройки температуры [Settings Temperature]", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public SettingsTemperature SettingsTemperature = new SettingsTemperature();
}
private void Teleport(BasePlayer player, Vector3 position, BasePlayer target = null) {
if (player.IsDead() && player.IsConnected) {
player.RespawnAt(position, Quaternion.identity);
return;
}
if (target == null) {
if (player.HasParent()) {
player.SetParent(null);
player.SendNetworkUpdate();
}
}
else {
if (target.HasParent()) {
player.SetParent(target.GetParentEntity());
player.SendNetworkUpdate();
}
}
var ret = Interface.Call("CanTeleport", player) as string;
if (ret != null) {
SendMessageWithoutLang(player, ret);
return;
}
if (player.net?.connection != null) player.ClientRPCPlayer(null, player, "StartLoading");
player.StartSleeping();
player.MovePosition(position);
if (player.net?.connection != null) player.ClientRPCPlayer(null, player, "ForcePositionTo", position);
if (player.net?.connection != null) player.SetPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot, true);
player.UpdateNetworkGroup();
//player.UpdatePlayerCollider(true, false);
player.SendNetworkUpdateImmediate(false);
if (player.net?.connection == null) return;
//TODO temporary for potential rust bug
try {
player.ClearEntityQueue(null);
}
catch {
//ignored
}
player.SendFullSnapshot();
}
private float GetTeleportTimeHome(ulong uid) {
float min = 9999f;
bool set = false;
foreach (var privilege in _config.SettingsHome.TeleportationTime) {
if (permission.UserHasPermission(uid.ToString(), privilege.Key)) {
min = Mathf.Min(min, privilege.Value);
set = true;
}
}
return set ? min : -1f;
}
[ChatCommand("atp")]
private void ChatCommandAtp(BasePlayer player, string command, string[] args) {
var data = PluginData.GetForPlayer(player.userID);
if (data == null) return;
data.AutoAccept = !data.AutoAccept;
SendMessage(player, "ATP.MODE", GetMessage(player, data.AutoAccept ? "ENABLED" : "DISABLED"));
}
private void SetHome(BasePlayer player, string name) {
var userId= player.userID;
var playerPosition = player.GetNetworkPosition();
var playerData = PluginData.GetForPlayer(player.userID);
if (playerData == null) return;
foreach (var home in playerData.HomesList) {
if (home.HomeName == name) {
SendMessage(player, "SETHOME.ALREADY.EXISTS");
return;
}
if (Vector3.Distance(playerPosition, home.HomePos) > 30) continue;
SendMessage(player, "SETHOME.CANCEL.RADIUS");
return;
}
if (GetHomeLimit(userId) == playerData.HomesList.Count) {
SendMessage(player, "SETHOME.CANCEL.MAXHOUSE");
return;
}
SleepingBag sleepingBag = null;
if (_config.SettingsHome.EnableSleepingBags) {
sleepingBag = CreateSleepingBag(player, playerPosition, $"{name}");
//List<BuildingBlock> foundations = new List<BuildingBlock>();
//Vis.Components(sleepingBag.transform.position, .3f, foundations);
var foundation = GetFoundation(sleepingBag.transform.position);
sleepingBag.buildingID = foundation[0].buildingID;
sleepingBag.gameObject.AddComponent<MarkerBag>();
sleepingBag.skinID = 214;
}
playerData.HomesList.Add(new PlayerData.Home(playerPosition, name, sleepingBag?.net.ID.Value ?? 0));
SendMessage(player, "SETHOME.SUCCESS", name);
}
private class TeleportMgr : MonoBehaviour {
public static Dictionary<BasePlayer, TeleportMgr> PlayerToManager = new Dictionary<BasePlayer, TeleportMgr>();
public static List<TeleportMgr> ManagersList = new List<TeleportMgr>();
private BasePlayer _player;
private double teleportTime;
public Request Request = null;
public List<Request> IncomingRequests = new List<Request>();
private double TimeTeleportation => teleportTime - GetCurrentTime();
private float TimeTP = 30f;
private float TimeHome = 30f;
private void Awake() {
_player = GetComponent<BasePlayer>();
if (_player == null) {
_plugin.PrintError("Failed to find player for teleport component! Deleting...");
Destroy(this);
return;
}
teleportTime = 0f;
PlayerToManager.Add(_player, this);
ManagersList.Add(this);
}
private void OnDestroy() {
if (_player != null) PlayerToManager.Remove(_player);
ManagersList.Remove(this);
}
private void TeleportTick() {
if (Request == null) {
CancelTeleport();
return;
}
try {
string ret = "";
if (Request.RequestConfirmed == false) {
ret = CheckRequest();
if (string.IsNullOrEmpty(ret) == false) {
_plugin.SendMessage(_player, ret);
CancelTeleport();
}
return;
}
ret = CheckTeleport();
if (string.IsNullOrEmpty(ret) == false) {
_plugin.SendMessage(_player, ret);
CancelTeleport();
return;
}
if (teleportTime - 1 > GetCurrentTime()) {
UpdateUI();
return;
}
_plugin.Teleport(_player, Request.Target == null ? Request.Position : Request.Target.ServerPosition);
var data = PluginData.GetForPlayer(_player.userID);
if (data == null) {
CancelTeleport();
return;
}
if (Request.IsHome) {
float coolDown = _plugin.GetTeleportCooldownHome(_player.userID);
var home = data.GetHome(Request.Position);
if (home == null) {
_plugin.SendMessage(_player, "HOME.NOT.FOUND.OR.REMOVED");
CancelTeleport();
return;
}
if (_config.SettingsHome.EnableSleepingBags) {
var bag = (SleepingBag) BaseNetworkable.serverEntities.Find(new NetworkableId(home.SleepingBagId));
if (bag != null) bag.unlockTime = Time.realtimeSinceStartup + coolDown;
}
data.CooldownHome = GetCurrentTime() + coolDown;
_plugin.SendMessage(_player, "TP.HOME.SUCCESS");
}
else if (Request.Monument != null) {
data.MonumentsCooldown.TryAdd(Request.Monument.Name, GetCurrentTime() + Request.Monument.CoolDown);
if (Request.Monument.CoolDownPublic > 0 && Request.Monument.CreatedBag != null) {
Request.Monument.CreatedBag.unlockTime = Time.realtimeSinceStartup + Request.Monument.CoolDownPublic;
}
_plugin.SendMessage(_player, "TPM.SUCCESS");
}
else {
_plugin.SendMessage(_player, "TP.PLAYER.SUCCESS", Request.Target.displayName);
_plugin.SendMessage(Request.Target, "TP.TARGET.SUCCESS", _player.displayName);
data.CooldownTeleport = GetCurrentTime() + _plugin.GetTeleportCooldownTpr(_player.userID);
}
}
catch (Exception e) {
_plugin.PrintError("Failed to update teleport tick! " + e);
Destroy(this);
}
CancelTeleport();
}
public bool HasRequest() {
return Request != null;
}
public void InitRequest(Vector3 teleportPos, bool isHome, BasePlayer target = null, SettingMonument.AvailableMonument monument = null) {
Request = new Request(_player, isHome, teleportPos, target, monument);
teleportTime = GetCurrentTime() + (isHome ? _plugin.GetTeleportTimeHome(_player.userID) : _plugin.GetTeleportTimeTpr(_player.userID));
if (monument != null) {
Request.RequestConfirmed = true;
teleportTime = GetCurrentTime() + monument.TeleportTime;
ShowUI();
}
if (isHome) {
Request.RequestConfirmed = true;
teleportTime = GetCurrentTime() + _plugin.GetTeleportTimeHome(_player.userID);
ShowUI();
}
if(IsInvoking(nameof(TeleportTick)) == false) InvokeRepeating(nameof(TeleportTick), 0.5f, 1f);
}
public void AcceptRequest() {
if (Request == null) return;
Request.RequestConfirmed = true;
teleportTime = GetCurrentTime() + _plugin.GetTeleportTimeTpr(_player.userID);
ShowUI();
}
private string CheckTeleport() {
if (_player.IsAlive() == false) return "CAN.TP.ALIVE";
if (_config.SettingsResolution.CantTeleportMounted && _player.isMounted) return "CAN.TP.MOUNTED";
if (_config.SettingsResolution.CantTeleportParent && _player.HasParent()) return "CAN.TP.PARENT";
if (_config.SettingsResolution.CantTeleportWater && _player.IsSwimming()) return "CAN.TP.WATER";
if (_config.SettingsResolution.CantTeleportWounded && _player.IsWounded()) return "CAN.TP.WOUNDED";
if (_config.SettingsResolution.CantTeleportCrawling && _player.IsWounded()) return "CAN.TP.CRAWLING";
if (_config.SettingsResolution.CantTeleportSwimming && _player.IsSwimming()) return "CAN.TP.SWIMMING";
if (_config.SettingsResolution.SettingsRadiation.CantTeleportRadiation && _player.metabolism.radiation_poison.value > _config.SettingsResolution.SettingsRadiation.NeedRadiationAmount) return "CAN.TP.RADIATION";
if (_config.SettingsResolution.SettingsBleeding.CantTeleportBleeding && _player.metabolism.bleeding.value > _config.SettingsResolution.SettingsBleeding.NeedBleedingAmount) return "CAN.TP.BLEEDING";
if (_config.SettingsResolution.SettingsTemperature.CantTeleportTemperature && _player.metabolism.temperature.value < _config.SettingsResolution.SettingsTemperature.MinNeedTemperature) return "CAN.TP.TEMPERATURE";
if (_config.SettingsResolution.CantTeleportInBuild && Request.Player.IsBuildingBlocked() && Request.IsHome) return "TP.CHECK.BUILD";
if (_config.SettingsResolution.CantTeleportInBuild && Request.IsHome == false && Request.Target != null && Request.Target.IsBuildingBlocked()) return "TP.CHECK.BUILD";
return string.Empty;
}
private string CheckRequest() {
if (Request.RequestTimeout > 30) return "REQUEST.CHECK.TIME.ENDED";
if (Request.Target.IsConnected == false) return "REQUEST.CHECK.DISCONNECT";
if (Request.Target.IsDead()) return "REQUEST.CHECK.DEAD";
if (Request.Target.IsWounded() && _config.SettingsResolution.CantTeleportWounded) return "REQUEST.CHECK.WOUNDED";
if (Request.Target.IsCrawling() && _config.SettingsResolution.CantTeleportCrawling) return "REQUEST.CHECK.WOUNDED";
return "";
}
private void ShowUI() {
CuiElementContainer container = new CuiElementContainer() {
{
new CuiPanel {
CursorEnabled = false, RectTransform = {
AnchorMin = "0.3447913 0.113889", AnchorMax = "0.640625 0.17037", OffsetMax = "0 0"
}
, Image = {
Color = "0.9686275 0.9215686 0.8823529 0.13529412"
}
}
, "Hud", LayerNotification
}
, {
new CuiLabel() {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 0.98"
}
, Text = {
Text = _plugin.GetMessage(_player, "TELEPORTATION.UI", TimeHelper.FormatTime(TimeSpan.FromSeconds(TimeTeleportation), language : _plugin.lang.GetLanguage(_player.UserIDString)).ToUpper()), Font = "RobotoCondensed-Bold.ttf", Align = TextAnchor.MiddleCenter, FontSize = 18, Color = GetColor("#FFFFFF", 0.7f)
}
,
}
, LayerNotification, LayerNotification + ".UpdateText"
}
}
;
CuiHelper.DestroyUi(_player, LayerNotification);
CuiHelper.AddUi(_player, container);
}
private void UpdateUI() {
CuiElementContainer container = new CuiElementContainer() {
{
new CuiLabel() {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 0.98"
}
, Text = {
Text = _plugin.GetMessage(_player, "TELEPORTATION.UI", TimeHelper.FormatTime(TimeSpan.FromSeconds(TimeTeleportation), language : _plugin.lang.GetLanguage(_player.UserIDString)).ToUpper()), Font = "RobotoCondensed-Bold.ttf", Align = TextAnchor.MiddleCenter, FontSize = 18, Color = GetColor("#FFFFFF", 0.7f)
}
,
}
, LayerNotification, LayerNotification + ".UpdateText"
}
}
;
CuiHelper.DestroyUi(_player, LayerNotification + ".UpdateText");
CuiHelper.AddUi(_player, container);
}
public void CancelTeleport() {
if (Request.Target != null) {
var manager = TeleportMgr.GetManager(Request.Target);
if (manager != null) {
manager.IncomingRequests.Remove(Request);
}
CuiHelper.DestroyUi(Request.Target, LayerNotification);
}
Request = null;
CancelInvoke(nameof(TeleportTick));
CuiHelper.DestroyUi(_player, LayerNotification);
}
public static TeleportMgr GetManager(BasePlayer player) {
TeleportMgr manager = null;
if (PlayerToManager.TryGetValue(player, out manage
// ... [Code preview truncated due to length. Full source in attached file] ...