VSMod_AriasServerUtils/AriasServerUtils/RTPFactory.cs

71 lines
No EOL
2.6 KiB
C#

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
{
/// <summary>
/// This function searches for a safe position, honoring the max RTP distance in the global configuration
/// </summary>
/// <param name="isp">The player to be teleported</param>
/// <returns>A random position +/- max distance from current position.</returns>
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 = 10;
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 > 25; i--)
{
bPos.Y = i;
curBlock = iswa.BlockAccessor.GetBlock(bPos);
if (curBlock.MatterState == EnumMatterState.Solid)
{
if (lastBlock != null && lastBlock.BlockMaterial == EnumBlockMaterial.Air &&
lastAboveLast != null && lastAboveLast.BlockMaterial == EnumBlockMaterial.Air)
{
// 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));
}
}