Compare commits
7
Commits
0e0e4e0f74
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
636a7dee98 | ||
|
|
1e4400555c | ||
|
|
0dfcc5396a | ||
|
|
c110ee2604 | ||
|
|
baf3ccbd93 | ||
|
|
3cf6db1d2a | ||
|
|
12219e6ef5 |
@@ -0,0 +1,140 @@
|
|||||||
|
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)
|
||||||
|
cuboids.Add(GrowOne(area));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cuboids;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static bool TryFindOverlappingClaimLink(
|
||||||
|
List<Cuboidi> areas,
|
||||||
|
ISet<int>? excludeGroupIds,
|
||||||
|
out int violatingGroupId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
foreach (int groupId in ClaimLinkModSystem.Registry.All)
|
||||||
|
{
|
||||||
|
if (excludeGroupIds != null && excludeGroupIds.Contains(groupId))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (Cuboidi bufferCuboid in GetBuffer(groupId))
|
||||||
|
foreach (Cuboidi area in areas)
|
||||||
|
if (area.Intersects(bufferCuboid))
|
||||||
|
{
|
||||||
|
violatingGroupId = groupId;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
violatingGroupId = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static bool TryFindOverlappingClaim(
|
||||||
|
List<Cuboidi> areas,
|
||||||
|
string excludeOwnerUid,
|
||||||
|
ISet<int>? excludeGroupIds,
|
||||||
|
out LandClaim? violatingClaim
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HashSet<LandClaim> excludedClaims = new();
|
||||||
|
if (excludeGroupIds != null)
|
||||||
|
foreach (int groupId in excludeGroupIds)
|
||||||
|
foreach (string uid in ClaimLinkModSystem.Registry.MemberUidsForGroup(groupId))
|
||||||
|
foreach (
|
||||||
|
int claimIndex in ClaimLinkModSystem.Registry.ClaimsForPlayerInGroup(
|
||||||
|
uid,
|
||||||
|
groupId
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
ClaimLinkModSystem.TryResolveOwnedClaim(
|
||||||
|
uid,
|
||||||
|
claimIndex,
|
||||||
|
out LandClaim? excludedClaim
|
||||||
|
)
|
||||||
|
&& excludedClaim != null
|
||||||
|
)
|
||||||
|
excludedClaims.Add(excludedClaim);
|
||||||
|
|
||||||
|
foreach (LandClaim claim in ClaimLinkModSystem.LandClaimAPI.All)
|
||||||
|
{
|
||||||
|
if (claim.OwnedByPlayerUid == excludeOwnerUid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (excludedClaims.Contains(claim))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (Cuboidi claimArea in claim.Areas)
|
||||||
|
foreach (Cuboidi area in areas)
|
||||||
|
if (area.Intersects(claimArea))
|
||||||
|
{
|
||||||
|
violatingClaim = claim;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
violatingClaim = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static ISet<int> MemberClaimLinkIds(string uid)
|
||||||
|
{
|
||||||
|
HashSet<int> groupIds = new();
|
||||||
|
var memberships = ClaimLinkModSystem.PlayerData.GetPlayerDataByUid(uid)?.PlayerGroupMemberships;
|
||||||
|
if (memberships == null)
|
||||||
|
return groupIds;
|
||||||
|
|
||||||
|
foreach (int groupId in memberships.Keys)
|
||||||
|
if (ClaimLinkModSystem.Registry.Exists(groupId))
|
||||||
|
groupIds.Add(groupId);
|
||||||
|
|
||||||
|
return groupIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static List<Cuboidi> GrowAreas(List<Cuboidi> areas)
|
||||||
|
{
|
||||||
|
List<Cuboidi> grown = new();
|
||||||
|
foreach (Cuboidi area in areas)
|
||||||
|
grown.Add(GrowOne(area));
|
||||||
|
return grown;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Cuboidi GrowOne(Cuboidi area)
|
||||||
|
{
|
||||||
|
Cuboidi normalized = new Cuboidi(
|
||||||
|
area.MinX,
|
||||||
|
area.MinY,
|
||||||
|
area.MinZ,
|
||||||
|
area.MaxX,
|
||||||
|
area.MaxY,
|
||||||
|
area.MaxZ
|
||||||
|
);
|
||||||
|
int bufferSize = ClaimLinkModSystem.Config.BufferSize;
|
||||||
|
return normalized.GrowBy(bufferSize, bufferSize, bufferSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Vintagestory.API.Common;
|
using Vintagestory.API.Common;
|
||||||
using Vintagestory.API.Config;
|
using Vintagestory.API.Config;
|
||||||
|
using Vintagestory.API.MathTools;
|
||||||
using Vintagestory.API.Server;
|
using Vintagestory.API.Server;
|
||||||
|
|
||||||
namespace ClaimLink;
|
namespace ClaimLink;
|
||||||
@@ -375,17 +376,56 @@ public static class ClaimLinkChatCommand
|
|||||||
int groupId = group.Uid;
|
int groupId = group.Uid;
|
||||||
string groupName = group.Name;
|
string groupName = group.Name;
|
||||||
|
|
||||||
if (!ClaimLinkModSystem.TryResolveOwnedClaim(playerUid, claimIndex, out _))
|
if (
|
||||||
return TextCommandResult.Error("You do not own that claim.");
|
!ClaimLinkModSystem.TryResolveOwnedClaim(playerUid, claimIndex, out LandClaim? claim)
|
||||||
|
|| claim == null
|
||||||
|
)
|
||||||
|
return TextCommandResult.Error($"You don't have a claim at index {claimIndex}.");
|
||||||
|
|
||||||
if (ClaimLinkModSystem.Registry.IsClaimLinked(playerUid, claimIndex))
|
if (ClaimLinkModSystem.Registry.IsClaimLinked(playerUid, claimIndex))
|
||||||
return TextCommandResult.Error("That claim is already part of a claim link.");
|
return TextCommandResult.Error("That claim is already part of a claim link.");
|
||||||
|
|
||||||
|
List<Cuboidi> grownAreas = ClaimLinkBuffer.GrowAreas(claim.Areas);
|
||||||
|
ISet<int> excludeGroupIds = new HashSet<int> { groupId };
|
||||||
|
|
||||||
|
if (
|
||||||
|
ClaimLinkBuffer.TryFindOverlappingClaimLink(
|
||||||
|
grownAreas,
|
||||||
|
excludeGroupIds,
|
||||||
|
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}'."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
ClaimLinkBuffer.TryFindOverlappingClaim(
|
||||||
|
grownAreas,
|
||||||
|
playerUid,
|
||||||
|
excludeGroupIds,
|
||||||
|
out LandClaim? violatingClaim
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return TextCommandResult.Error(
|
||||||
|
$"Cannot link that claim, its buffer would overlap the claim owned by {violatingClaim!.LastKnownOwnerName}."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
string claimDesc = DescribeClaim(playerUid, claimIndex);
|
string claimDesc = DescribeClaim(playerUid, claimIndex);
|
||||||
return Stage(
|
return Stage(
|
||||||
playerUid,
|
playerUid,
|
||||||
groupId,
|
groupId,
|
||||||
$"{claimDesc} will be linked into '{groupName}'.",
|
$"'{claimDesc}' will be linked into '{groupName}'.",
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
bool stillMember =
|
bool stillMember =
|
||||||
@@ -397,9 +437,9 @@ public static class ClaimLinkChatCommand
|
|||||||
|
|
||||||
bool success = ClaimLinkModSystem.Registry.AddEntry(playerUid, groupId, claimIndex);
|
bool success = ClaimLinkModSystem.Registry.AddEntry(playerUid, groupId, claimIndex);
|
||||||
return success
|
return success
|
||||||
? TextCommandResult.Success($"Linked {claimDesc} to '{groupName}'.")
|
? TextCommandResult.Success($"Linked '{claimDesc}' to '{groupName}'.")
|
||||||
: TextCommandResult.Error(
|
: TextCommandResult.Error(
|
||||||
$"Unable to link {claimIndex} to '{groupName}' it is currently being modified."
|
$"Unable to link claim {claimIndex} to '{groupName}', it is currently being modified."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -422,11 +462,11 @@ public static class ClaimLinkChatCommand
|
|||||||
return Stage(
|
return Stage(
|
||||||
playerUid,
|
playerUid,
|
||||||
(int)groupId,
|
(int)groupId,
|
||||||
$"{claimDesc} will be unlinked from '{groupName}'.",
|
$"'{claimDesc}' will be unlinked from '{groupName}'.",
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
ClaimLinkModSystem.Registry.RemoveEntry(playerUid, (int)groupId, claimIndex);
|
ClaimLinkModSystem.Registry.RemoveEntry(playerUid, (int)groupId, claimIndex);
|
||||||
return TextCommandResult.Success($"Unlinked {claimDesc} from '{groupName}'.");
|
return TextCommandResult.Success($"Unlinked '{claimDesc}' from '{groupName}'.");
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -806,7 +846,7 @@ public static class ClaimLinkChatCommand
|
|||||||
|
|
||||||
ClaimLinkModSystem.Registry.RemoveEntry(targetUid, (int)groupId, claimIndex);
|
ClaimLinkModSystem.Registry.RemoveEntry(targetUid, (int)groupId, claimIndex);
|
||||||
return TextCommandResult.Success(
|
return TextCommandResult.Success(
|
||||||
$"Unlinked {claimDesc} from '{groupName}' (owned by {playerName})."
|
$"Unlinked '{claimDesc}' from '{groupName}' (owned by {playerName})."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace ClaimLink;
|
||||||
|
|
||||||
|
internal class ClaimLinkConfig
|
||||||
|
{
|
||||||
|
public int BufferSize = 16;
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ public class ClaimLinkModSystem : ModSystem
|
|||||||
internal static IGroupManager Groups = null!;
|
internal static IGroupManager Groups = null!;
|
||||||
internal static IWorldAccessor World = null!;
|
internal static IWorldAccessor World = null!;
|
||||||
internal static IPlayerDataManager PlayerData = null!;
|
internal static IPlayerDataManager PlayerData = null!;
|
||||||
|
internal static ClaimLinkConfig Config = null!;
|
||||||
internal CommandListener? CmdListener;
|
internal CommandListener? CmdListener;
|
||||||
internal GroupCommandListener? GroupCmdListener;
|
internal GroupCommandListener? GroupCmdListener;
|
||||||
|
|
||||||
@@ -25,6 +26,8 @@ public class ClaimLinkModSystem : ModSystem
|
|||||||
Groups = api.Groups;
|
Groups = api.Groups;
|
||||||
Logger = api.Logger;
|
Logger = api.Logger;
|
||||||
PlayerData = api.PlayerData;
|
PlayerData = api.PlayerData;
|
||||||
|
Config = api.LoadModConfig<ClaimLinkConfig>("claimlink.json") ?? new ClaimLinkConfig();
|
||||||
|
api.StoreModConfig(Config, "claimlink.json");
|
||||||
Registry = new ClaimLinkRegistry(api.WorldManager.SaveGame);
|
Registry = new ClaimLinkRegistry(api.WorldManager.SaveGame);
|
||||||
|
|
||||||
CmdListener = new CommandListener();
|
CmdListener = new CommandListener();
|
||||||
@@ -32,6 +35,7 @@ public class ClaimLinkModSystem : ModSystem
|
|||||||
GroupCmdListener = new GroupCommandListener();
|
GroupCmdListener = new GroupCommandListener();
|
||||||
CommandHookModSystem.Register(GroupCmdListener);
|
CommandHookModSystem.Register(GroupCmdListener);
|
||||||
ClaimLinkChatCommand.Register(api);
|
ClaimLinkChatCommand.Register(api);
|
||||||
|
ClaimLinkVisualizerNetwork.Start(api);
|
||||||
|
|
||||||
api.Event.PlayerDisconnect += CommandListener.OnPlayerDisconnect;
|
api.Event.PlayerDisconnect += CommandListener.OnPlayerDisconnect;
|
||||||
api.Event.PlayerDisconnect += GroupCommandListener.OnPlayerDisconnect;
|
api.Event.PlayerDisconnect += GroupCommandListener.OnPlayerDisconnect;
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Vintagestory.API.MathTools;
|
||||||
|
using Vintagestory.API.Server;
|
||||||
|
|
||||||
|
namespace ClaimLink;
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public class ClaimLinkBufferRequest { }
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public class ClaimLinkBufferCuboidDto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public int MinX;
|
||||||
|
|
||||||
|
[ProtoMember(2)]
|
||||||
|
public int MinY;
|
||||||
|
|
||||||
|
[ProtoMember(3)]
|
||||||
|
public int MinZ;
|
||||||
|
|
||||||
|
[ProtoMember(4)]
|
||||||
|
public int MaxX;
|
||||||
|
|
||||||
|
[ProtoMember(5)]
|
||||||
|
public int MaxY;
|
||||||
|
|
||||||
|
[ProtoMember(6)]
|
||||||
|
public int MaxZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public class ClaimLinkBufferEntryDto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public int GroupId;
|
||||||
|
|
||||||
|
[ProtoMember(2)]
|
||||||
|
public List<ClaimLinkBufferCuboidDto> Cuboids = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public class ClaimLinkBufferResponse
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public List<ClaimLinkBufferEntryDto> Entries = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class ClaimLinkVisualizerNetwork
|
||||||
|
{
|
||||||
|
internal const string ChannelName = "claimlinkvisualizer";
|
||||||
|
|
||||||
|
internal static void Start(ICoreServerAPI api)
|
||||||
|
{
|
||||||
|
api.Network
|
||||||
|
.RegisterChannel(ChannelName)
|
||||||
|
.RegisterMessageType<ClaimLinkBufferRequest>()
|
||||||
|
.RegisterMessageType<ClaimLinkBufferResponse>()
|
||||||
|
.SetMessageHandler<ClaimLinkBufferRequest>((fromPlayer, _) =>
|
||||||
|
SendBuffers(api, fromPlayer)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SendBuffers(ICoreServerAPI api, IServerPlayer toPlayer)
|
||||||
|
{
|
||||||
|
ClaimLinkBufferResponse response = new();
|
||||||
|
|
||||||
|
BlockPos playerPos = toPlayer.Entity.Pos.AsBlockPos;
|
||||||
|
int radius = toPlayer.WorldData.LastApprovedViewDistance;
|
||||||
|
|
||||||
|
foreach (int groupId in ClaimLinkModSystem.Registry.All)
|
||||||
|
{
|
||||||
|
ClaimLinkBufferEntryDto entry = new() { GroupId = groupId };
|
||||||
|
foreach (Cuboidi cuboid in ClaimLinkBuffer.GetBuffer(groupId))
|
||||||
|
{
|
||||||
|
if (!IsNearby(cuboid, playerPos, radius))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
entry.Cuboids.Add(
|
||||||
|
new ClaimLinkBufferCuboidDto
|
||||||
|
{
|
||||||
|
MinX = cuboid.MinX,
|
||||||
|
MinY = cuboid.MinY,
|
||||||
|
MinZ = cuboid.MinZ,
|
||||||
|
MaxX = cuboid.MaxX,
|
||||||
|
MaxY = cuboid.MaxY,
|
||||||
|
MaxZ = cuboid.MaxZ,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.Cuboids.Count > 0)
|
||||||
|
response.Entries.Add(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
api.Network.GetChannel(ChannelName).SendPacket(response, toPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsNearby(Cuboidi cuboid, BlockPos playerPos, int radius) =>
|
||||||
|
cuboid.MinX <= playerPos.X + radius
|
||||||
|
&& cuboid.MaxX >= playerPos.X - radius
|
||||||
|
&& cuboid.MinY <= playerPos.Y + radius
|
||||||
|
&& cuboid.MaxY >= playerPos.Y - radius
|
||||||
|
&& cuboid.MinZ <= playerPos.Z + radius
|
||||||
|
&& cuboid.MaxZ >= playerPos.Z - radius;
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using CommandHook;
|
using CommandHook;
|
||||||
using Vintagestory.API.Common;
|
using Vintagestory.API.Common;
|
||||||
|
using Vintagestory.API.Config;
|
||||||
|
using Vintagestory.API.MathTools;
|
||||||
using Vintagestory.API.Server;
|
using Vintagestory.API.Server;
|
||||||
|
|
||||||
namespace ClaimLink;
|
namespace ClaimLink;
|
||||||
@@ -14,6 +16,8 @@ public class CommandListener : ICommandHookListener
|
|||||||
public CommandRegistration Registration => new(Before, After);
|
public CommandRegistration Registration => new(Before, After);
|
||||||
|
|
||||||
internal static Dictionary<string, int> PendingLoads = new Dictionary<string, int>();
|
internal static Dictionary<string, int> PendingLoads = new Dictionary<string, int>();
|
||||||
|
internal static Dictionary<string, List<Cuboidi>?> PendingSaveChecks =
|
||||||
|
new Dictionary<string, List<Cuboidi>?>();
|
||||||
|
|
||||||
private delegate void SubHandler(Caller caller, CmdArgs args);
|
private delegate void SubHandler(Caller caller, CmdArgs args);
|
||||||
|
|
||||||
@@ -28,6 +32,7 @@ public class CommandListener : ICommandHookListener
|
|||||||
private static readonly Dictionary<string, SubHandler> claimSub = new()
|
private static readonly Dictionary<string, SubHandler> claimSub = new()
|
||||||
{
|
{
|
||||||
["load"] = ClaimLoad,
|
["load"] = ClaimLoad,
|
||||||
|
["new"] = ClaimNew,
|
||||||
["save"] = ClaimSave,
|
["save"] = ClaimSave,
|
||||||
["cancel"] = ClaimCancel,
|
["cancel"] = ClaimCancel,
|
||||||
};
|
};
|
||||||
@@ -58,7 +63,89 @@ public class CommandListener : ICommandHookListener
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void After(TextCommandCallingArgs args, TextCommandResult result) { }
|
private void After(TextCommandCallingArgs args, TextCommandResult result)
|
||||||
|
{
|
||||||
|
if (args.Caller.Player == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
string uid = args.Caller.Player.PlayerUID;
|
||||||
|
if (!PendingSaveChecks.Remove(uid, out List<Cuboidi>? snapshot))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (result.Status != EnumCommandStatus.Success)
|
||||||
|
return;
|
||||||
|
|
||||||
|
List<LandClaim> allClaims = ClaimLinkModSystem.LandClaimAPI.All;
|
||||||
|
if (allClaims.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LandClaim savedClaim = allClaims[allClaims.Count - 1];
|
||||||
|
if (savedClaim.OwnedByPlayerUid != uid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int? linkedGroupId = null;
|
||||||
|
if (ClaimLinkModSystem.TryResolveClaimIndex(uid, savedClaim, out int savedIndex))
|
||||||
|
linkedGroupId = ClaimLinkModSystem.Registry.FindGroupContaining(uid, savedIndex);
|
||||||
|
|
||||||
|
bool isLinked = linkedGroupId != null;
|
||||||
|
List<Cuboidi> checkAreas = isLinked
|
||||||
|
? ClaimLinkBuffer.GrowAreas(savedClaim.Areas)
|
||||||
|
: savedClaim.Areas;
|
||||||
|
|
||||||
|
ISet<int> excludeGroupIds = isLinked
|
||||||
|
? new HashSet<int> { linkedGroupId!.Value }
|
||||||
|
: ClaimLinkBuffer.MemberClaimLinkIds(uid);
|
||||||
|
|
||||||
|
LandClaim? violatingClaim = null;
|
||||||
|
bool violatesClaimLink = ClaimLinkBuffer.TryFindOverlappingClaimLink(
|
||||||
|
checkAreas,
|
||||||
|
excludeGroupIds,
|
||||||
|
out int violatingGroupId
|
||||||
|
);
|
||||||
|
bool violatesClaim =
|
||||||
|
isLinked
|
||||||
|
&& !violatesClaimLink
|
||||||
|
&& ClaimLinkBuffer.TryFindOverlappingClaim(
|
||||||
|
checkAreas,
|
||||||
|
uid,
|
||||||
|
excludeGroupIds,
|
||||||
|
out violatingClaim
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!violatesClaimLink && !violatesClaim)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ClaimLinkModSystem.LandClaimAPI.Remove(savedClaim);
|
||||||
|
|
||||||
|
string reason = violatesClaimLink
|
||||||
|
? (
|
||||||
|
ClaimLinkModSystem.Groups.PlayerGroupsById.TryGetValue(
|
||||||
|
violatingGroupId,
|
||||||
|
out PlayerGroup? violatingGroup
|
||||||
|
)
|
||||||
|
? $"it overlaps the protected buffer of '{violatingGroup!.Name}'"
|
||||||
|
: "it overlaps the protected buffer of another claim link"
|
||||||
|
)
|
||||||
|
: $"its buffer would overlap the claim owned by {violatingClaim!.LastKnownOwnerName}";
|
||||||
|
|
||||||
|
if (snapshot != null)
|
||||||
|
{
|
||||||
|
savedClaim.Areas.Clear();
|
||||||
|
savedClaim.Areas.AddRange(snapshot);
|
||||||
|
ClaimLinkModSystem.LandClaimAPI.Add(savedClaim);
|
||||||
|
NotifyPlayer(args.Caller.Player, $"Your claim growth was reverted: {reason}.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NotifyPlayer(args.Caller.Player, $"Your claim was rejected: {reason}.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void NotifyPlayer(IPlayer player, string message)
|
||||||
|
{
|
||||||
|
if (player is IServerPlayer sp)
|
||||||
|
sp.SendMessage(GlobalConstants.GeneralChatGroup, message, EnumChatType.Notification);
|
||||||
|
}
|
||||||
|
|
||||||
private static void Claim(Caller caller, CmdArgs args)
|
private static void Claim(Caller caller, CmdArgs args)
|
||||||
{
|
{
|
||||||
@@ -79,9 +166,22 @@ public class CommandListener : ICommandHookListener
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
string uid = caller.Player.PlayerUID;
|
string uid = caller.Player.PlayerUID;
|
||||||
|
PendingSaveChecks[uid] = null;
|
||||||
|
|
||||||
if (!PendingLoads.TryGetValue(uid, out int pendingIndex))
|
if (!PendingLoads.TryGetValue(uid, out int pendingIndex))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (
|
||||||
|
ClaimLinkModSystem.TryResolveOwnedClaim(uid, pendingIndex, out LandClaim? existingClaim)
|
||||||
|
&& existingClaim != null
|
||||||
|
)
|
||||||
|
{
|
||||||
|
List<Cuboidi> snapshot = new();
|
||||||
|
foreach (Cuboidi area in existingClaim.Areas)
|
||||||
|
snapshot.Add(area.Clone());
|
||||||
|
PendingSaveChecks[uid] = snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
ClaimLinkModSystem.Registry.ClaimSaved(uid, pendingIndex);
|
ClaimLinkModSystem.Registry.ClaimSaved(uid, pendingIndex);
|
||||||
PendingLoads.Remove(uid);
|
PendingLoads.Remove(uid);
|
||||||
ClaimLinkChatCommand.PendingActions.Remove(uid);
|
ClaimLinkChatCommand.PendingActions.Remove(uid);
|
||||||
@@ -99,6 +199,14 @@ public class CommandListener : ICommandHookListener
|
|||||||
PendingLoads[caller.Player.PlayerUID] = (int)claimIndex;
|
PendingLoads[caller.Player.PlayerUID] = (int)claimIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ClaimNew(Caller caller, CmdArgs args)
|
||||||
|
{
|
||||||
|
if (caller.Player == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PendingLoads.Remove(caller.Player.PlayerUID);
|
||||||
|
}
|
||||||
|
|
||||||
private static void ClaimCancel(Caller caller, CmdArgs args)
|
private static void ClaimCancel(Caller caller, CmdArgs args)
|
||||||
{
|
{
|
||||||
if (caller.Player == null)
|
if (caller.Player == null)
|
||||||
@@ -161,6 +269,7 @@ public class CommandListener : ICommandHookListener
|
|||||||
internal static void OnPlayerDisconnect(IServerPlayer player)
|
internal static void OnPlayerDisconnect(IServerPlayer player)
|
||||||
{
|
{
|
||||||
PendingLoads.Remove(player.PlayerUID);
|
PendingLoads.Remove(player.PlayerUID);
|
||||||
|
PendingSaveChecks.Remove(player.PlayerUID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
"anth64"
|
"anth64"
|
||||||
],
|
],
|
||||||
"description": "Link claims together with groups.",
|
"description": "Link claims together with groups.",
|
||||||
"version": "0.1.0",
|
"version": "0.3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"game": "1.22.5",
|
"game": "1.22.5",
|
||||||
"commandhook": "2.1.0"
|
"commandhook": "2.1.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user