From 86ff08b9e74adb20981d1193e07c6d014ae93154 Mon Sep 17 00:00:00 2001 From: zontreck Date: Thu, 6 Mar 2025 16:48:41 -0700 Subject: [PATCH] Implement the rtp function #2 --- AriasServerUtils/ASUModSystem.cs | 9 +++ AriasServerUtils/EventHandler.cs | 31 ++++++++ AriasServerUtils/Globals.cs | 1 + AriasServerUtils/RTPFactory.cs | 71 +++++++++++++++++++ .../assets/ariasserverutils/lang/en.json | 1 + 5 files changed, 113 insertions(+) create mode 100644 AriasServerUtils/RTPFactory.cs diff --git a/AriasServerUtils/ASUModSystem.cs b/AriasServerUtils/ASUModSystem.cs index 0755aac..b7bc9a2 100644 --- a/AriasServerUtils/ASUModSystem.cs +++ b/AriasServerUtils/ASUModSystem.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using Vintagestory.API.Client; using Vintagestory.API.Common; +using Vintagestory.API.Common.CommandAbbr; using Vintagestory.API.Common.Entities; using Vintagestory.API.Config; using Vintagestory.API.MathTools; @@ -137,6 +138,14 @@ namespace AriasServerUtils .WithDescription("Percentage of players required to sleep before sleeping through the night") .HandleWith(Events.HandleUpdateASUPSP) .EndSubCommand() + .BeginSubCommand("rtp") + .RequiresPrivilege(Privilege.controlserver) + .WithArgs( + parsers.Int("maxDistance") + ) + .WithDescription("Update RTP Max block distance. Plus and/or minus this distance from player current position") + .HandleWith(Events.HandleUpdateASURTPMax) + .EndSubCommand() .EndSubCommand() .BeginSubCommand("help") .RequiresPrivilege(Privilege.chat) diff --git a/AriasServerUtils/EventHandler.cs b/AriasServerUtils/EventHandler.cs index 1df0360..9dcb867 100644 --- a/AriasServerUtils/EventHandler.cs +++ b/AriasServerUtils/EventHandler.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using Vintagestory.API.Common; using Vintagestory.API.Config; +using Vintagestory.API.MathTools; using Vintagestory.API.Server; namespace AriasServerUtils @@ -41,6 +42,23 @@ namespace AriasServerUtils internal static TextCommandResult HandleRTP(TextCommandCallingArgs args) { + if (args.Caller is IServerPlayer isp) + { + ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:rtp-search")); + + PlayerPosition pPos = RTPFactory.GetRandomPosition(isp); + if (pPos == null) + { + ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:rtp-fail")); + } + Vec2i origin = new((int)isp.Entity.Pos.X, (int)isp.Entity.Pos.Z); + Vec2i npos = new(pPos.X, pPos.Z); + + float distance = RTPFactory.GetDistance(origin, npos); + + ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:rtp", distance)); + + } return TextCommandResult.Success(); } @@ -349,5 +367,18 @@ namespace AriasServerUtils return TextCommandResult.Success(); } + + internal static TextCommandResult HandleUpdateASURTPMax(TextCommandCallingArgs args) + { + if (args[0] is int maxDist) + { + ServerUtilities.config.MaxRTPBlockDistance = maxDist; + ServerUtilities.MarkDirty(); + + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig")); + } + + return TextCommandResult.Success(); + } } } \ No newline at end of file diff --git a/AriasServerUtils/Globals.cs b/AriasServerUtils/Globals.cs index 223b195..98f125c 100644 --- a/AriasServerUtils/Globals.cs +++ b/AriasServerUtils/Globals.cs @@ -18,6 +18,7 @@ namespace AriasServerUtils public bool onlyAdminsCreateWarps { get; set; } = true; public int MaxBackCache { get; set; } = 10; public int PlayerSleepingPercentage { get; set; } = 50; + public int MaxRTPBlockDistance { get; set; } = 5000; public PlayerPosition Spawn { get; set; } diff --git a/AriasServerUtils/RTPFactory.cs b/AriasServerUtils/RTPFactory.cs new file mode 100644 index 0000000..2018d31 --- /dev/null +++ b/AriasServerUtils/RTPFactory.cs @@ -0,0 +1,71 @@ +using System; +using System.Data; +using System.Numerics; +using AriasServerUtils; +using Vintagestory.API.Common; +using Vintagestory.API.Common.Entities; +using Vintagestory.API.MathTools; +using Vintagestory.API.Server; +using Vintagestory.GameContent; + +public class RTPFactory +{ + /// + /// This function searches for a safe position, honoring the max RTP distance in the global configuration + /// + /// The player to be teleported + /// A random position +/- max distance from current position. + public static PlayerPosition GetRandomPosition(IServerPlayer isp) + { + Random rng = new Random(); + EntityPos vPos = isp.Entity.Pos; + BlockPos bPos = new BlockPos(isp.Entity.Pos.Dimension); + IServerWorldAccessor iswa = isp.Entity.World as IServerWorldAccessor; + + int tries = 5; + PlayerPosition PPos = PlayerPosition.from(isp.Entity); + + while (tries-- > 0) + { + // Generate random X and Z within max RTP distance + bPos.X = (int)vPos.X + rng.Next(-ServerUtilities.config.MaxRTPBlockDistance, ServerUtilities.config.MaxRTPBlockDistance); + bPos.Z = (int)vPos.Z + rng.Next(-ServerUtilities.config.MaxRTPBlockDistance, ServerUtilities.config.MaxRTPBlockDistance); + bPos.Y = 255; + + Block lastAboveLast = null; + Block lastBlock = null; + Block curBlock; + + // Scan downwards to find a valid landing spot + for (int i = 255; i > 50; i--) + { + bPos.Y = i; + curBlock = iswa.BlockAccessor.GetBlock(bPos); + + if (curBlock != null && !curBlock.IsLiquid() && curBlock.MatterState == EnumMatterState.Solid) + { + if (lastBlock != null && lastBlock.MatterState == EnumMatterState.Gas && + lastAboveLast != null && lastAboveLast.MatterState == EnumMatterState.Gas) + { + // Found a valid spot: curBlock is solid, lastBlock & lastAboveLast are gas (air) + PPos.X = bPos.X; + PPos.Y = bPos.Y + 1; + PPos.Z = bPos.Z; + + return PPos; + } + } + + lastAboveLast = lastBlock; + lastBlock = curBlock; + } + } + + return null; // Return null if no valid position is found after retries + } + public static float GetDistance(Vec2i pos1, Vec2i pos2) + { + return MathF.Sqrt(MathF.Pow(pos2.X - pos1.X, 2) + MathF.Pow(pos2.Y - pos1.Y, 2)); + } + +} \ No newline at end of file diff --git a/AriasServerUtils/assets/ariasserverutils/lang/en.json b/AriasServerUtils/assets/ariasserverutils/lang/en.json index eb944c0..52606b7 100644 --- a/AriasServerUtils/assets/ariasserverutils/lang/en.json +++ b/AriasServerUtils/assets/ariasserverutils/lang/en.json @@ -34,6 +34,7 @@ "rtp-search": "Searching for a random position...", "rtp": "You have been teleported [{0}] blocks away!", + "rtp-fail": "Giving up on RTP search. No valid position could be found. Try again later", "cmd-cooldown": "[{0}] is currently on cooldown. You can use this command again in [{1}]" }