feat: enforce buffer-zone non-overlap on /claimlink link

This commit is contained in:
2026-07-26 15:30:35 +02:00
parent 3cf6db1d2a
commit baf3ccbd93
2 changed files with 87 additions and 1 deletions
+64
View File
@@ -0,0 +1,64 @@
using System.Collections.Generic;
using Vintagestory.API.Common;
using Vintagestory.API.MathTools;
namespace ClaimLink;
internal static class ClaimLinkBuffer
{
internal static List<Cuboidi> GetBuffer(int groupId)
{
List<Cuboidi> cuboids = new();
foreach (string uid in ClaimLinkModSystem.Registry.MemberUidsForGroup(groupId))
{
foreach (
int claimIndex in ClaimLinkModSystem.Registry.ClaimsForPlayerInGroup(uid, groupId)
)
{
if (
!ClaimLinkModSystem.TryResolveOwnedClaim(uid, claimIndex, out LandClaim? claim)
|| claim == null
)
continue;
foreach (Cuboidi area in claim.Areas)
{
int bufferSize = ClaimLinkModSystem.Config.BufferSize;
cuboids.Add(area.Clone().GrowBy(bufferSize, bufferSize, bufferSize));
}
}
}
return cuboids;
}
internal static bool TryFindOverlappingClaimLink(
List<Cuboidi> areas,
int? excludeGroupId,
out int violatingGroupId
)
{
int bufferSize = ClaimLinkModSystem.Config.BufferSize;
List<Cuboidi> grownAreas = new();
foreach (Cuboidi area in areas)
grownAreas.Add(area.Clone().GrowBy(bufferSize, bufferSize, bufferSize));
foreach (int groupId in ClaimLinkModSystem.Registry.All)
{
if (groupId == excludeGroupId)
continue;
foreach (Cuboidi bufferCuboid in GetBuffer(groupId))
foreach (Cuboidi grownArea in grownAreas)
if (grownArea.Intersects(bufferCuboid))
{
violatingGroupId = groupId;
return true;
}
}
violatingGroupId = -1;
return false;
}
}
+23 -1
View File
@@ -375,12 +375,34 @@ public static class ClaimLinkChatCommand
int groupId = group.Uid;
string groupName = group.Name;
if (!ClaimLinkModSystem.TryResolveOwnedClaim(playerUid, claimIndex, out _))
if (
!ClaimLinkModSystem.TryResolveOwnedClaim(playerUid, claimIndex, out LandClaim? claim)
|| claim == null
)
return TextCommandResult.Error("You do not own that claim.");
if (ClaimLinkModSystem.Registry.IsClaimLinked(playerUid, claimIndex))
return TextCommandResult.Error("That claim is already part of a claim link.");
if (
ClaimLinkBuffer.TryFindOverlappingClaimLink(
claim.Areas,
groupId,
out int violatingGroupId
)
)
{
string violatingName = ClaimLinkModSystem.Groups.PlayerGroupsById.TryGetValue(
violatingGroupId,
out PlayerGroup? violatingGroup
)
? violatingGroup!.Name
: "another claim link";
return TextCommandResult.Error(
$"Cannot link that claim, it overlaps the protected buffer of '{violatingName}'."
);
}
string claimDesc = DescribeClaim(playerUid, claimIndex);
return Stage(
playerUid,