From baf3ccbd93138e079c6c3e55bc223722026f0d24 Mon Sep 17 00:00:00 2001 From: anth64 Date: Sun, 26 Jul 2026 15:30:35 +0200 Subject: [PATCH] feat: enforce buffer-zone non-overlap on /claimlink link --- ClaimLink/ClaimLinkBuffer.cs | 64 +++++++++++++++++++++++++++++++ ClaimLink/ClaimLinkChatCommand.cs | 24 +++++++++++- 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 ClaimLink/ClaimLinkBuffer.cs diff --git a/ClaimLink/ClaimLinkBuffer.cs b/ClaimLink/ClaimLinkBuffer.cs new file mode 100644 index 0000000..36fbf98 --- /dev/null +++ b/ClaimLink/ClaimLinkBuffer.cs @@ -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 GetBuffer(int groupId) + { + List 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 areas, + int? excludeGroupId, + out int violatingGroupId + ) + { + int bufferSize = ClaimLinkModSystem.Config.BufferSize; + List 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; + } +} diff --git a/ClaimLink/ClaimLinkChatCommand.cs b/ClaimLink/ClaimLinkChatCommand.cs index a171a36..2d394d1 100644 --- a/ClaimLink/ClaimLinkChatCommand.cs +++ b/ClaimLink/ClaimLinkChatCommand.cs @@ -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,