Skip to content

Commit

Permalink
Merge pull request #28 from jonathan-robertson/dev
Browse files Browse the repository at this point in the history
Update Inbox to Work Outside of Land Claims
  • Loading branch information
jonathan-robertson authored Apr 22, 2023
2 parents 0bb15c9 + cca502b commit cfa1d03
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 206 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.4.0] - 2023-04-22

- take advantage of land claim if one is present
- update inbox to work outside of land claims

## [1.3.1] - 2023-03-19

- add console command to toggle debug mode
Expand Down
2 changes: 0 additions & 2 deletions Config/Localization.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,3 @@ cntSecureRoboticInboxTip01_title,Journal Tip,,"Robotic Inbox (General Info) [ff8
cntSecureRoboticInboxTip01,Journal Tip,,"The [00ff80]Secure Robotic Inbox[-] is a new block meant to streamline item/resource organization [ff8000]within an active LCB area[-] to help you dump your loot quickly and get back into the action. When the Inbox is closed, it will automatically distribute and sort its items into nearby container(s) with matching item types (so long as those containers are also within the same LCB area).\n\nFor security reasons, [ff8000]the Inbox will need to use the same password as any locked storage containers it tries to organize[-].\n\nWhile any secure or insecure player-placed storage container will work with the Inbox, [00ff80]Writable Storage Boxes will describe how the Inbox is interacting with them[-], making them the recommended type of container to place near an Inbox.\n\nAny items in the Inbox that are not able to be matched with another container will be left there until you have time to decide which container to store them in.\n\nThis new Inbox can be crafted at the Workbench or found for sale by a trader whenever you're ready to try it out."
cntSecureRoboticInboxTip02_title,Journal Tip,,"Robotic Inbox (Security Info) [ff8000][MOD]"
cntSecureRoboticInboxTip02,Journal Tip,,"The [00ff80]Secure Robotic Inbox[-] has certain requirements depending on the state of the containers it interacts with.\n\nIf the following requirements aren't met, the Inbox will have to skip interactions with the target containers until the necessary adjustments are made:\n1. containers not placed by players (ex: POI containers) are ignored.\n2. player backpacks and vehicles are ignored.\n3. both Inbox and target container must be within the same LCB area.\n4. target container must be within 5 meters of Inbox, both horizontally and vertically (imagine a cube 11x11 in size with the inbox at the center).\n5. if target container is locked, Inbox must also be lockable, in a locked state, and set to the same password as target container.\n\n[!] Using [00ff80]Writable Storage Boxes[-] will make configuring your storage area far easier. A short explanation for why a container could not be accessed is provided for a few seconds on each writable container the Inbox is unable to access."

notifyRoboticInboxNotInLcbTip,buffs,Buff,"A Robotic Inbox must be placed within range of an active LCB"
9 changes: 0 additions & 9 deletions Config/buffs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,4 @@
<triggered_effect trigger="onSelfEnteredGame" action="AddJournalEntry" journal="cntSecureRoboticInboxTip02" />
</effect_group>
</append>
<append xpath="/buffs">
<buff name="notifyRoboticInboxNotInLcb">
<duration value="2" />
<stack_type value="ignore" />
<effect_group>
<triggered_effect trigger="onSelfBuffStart" action="ShowToolbeltMessage" message_key="notifyRoboticInboxNotInLcbTip" />
</effect_group>
</buff>
</append>
</config>
2 changes: 1 addition & 1 deletion ModInfo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<Name value="Robotic Inbox" />
<Description value="A special container that automatically sorts and distributes items to other nearby storage containers." />
<Author value="Jonathan Robertson (Kanaverum)" />
<Version value="1.3.1" />
<Version value="1.4.0" />
<Website value="https://github.com/jonathan-robertson/robotic-inbox" />
</ModInfo>
</xml>
Binary file modified RoboticInbox.dll
Binary file not shown.
145 changes: 0 additions & 145 deletions src/NetPackageSetBlock_Patches.cs

This file was deleted.

File renamed without changes.
6 changes: 2 additions & 4 deletions src/RoboticInbox.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,13 @@
<Compile Include="ConsoleCmdRoboticInbox.cs" />
<Compile Include="ModApi.cs" />
<Compile Include="ModLog.cs" />
<Compile Include="NetPackageSetBlock_Patches.cs" />
<Compile Include="GameManager_Patches.cs" />
<Compile Include="Patches.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StorageManager.cs" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
<PostBuildEvent />
</PropertyGroup>
</Project>
97 changes: 52 additions & 45 deletions src/StorageManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,46 @@ internal static void Distribute(int clrIdx, Vector3i sourcePos)
return;
}

// Limit min/max to only points **within** the same LCB as the source
if (!GetBoundsWithinWorldAndLandClaim(sourcePos, out var min, out var max))
GetBoundsWithinWorldAndLandClaim(sourcePos, out var min, out var max);
_ = ThreadManager.StartCoroutine(OrganizeCoroutine(clrIdx, sourcePos, sourceContainer, min, max));
}

private static void GetBoundsWithinWorldAndLandClaim(Vector3i source, out Vector3i min, out Vector3i max)
{
min = max = default;

if (!GameManager.Instance.World.GetWorldExtent(out var _minMapSize, out var _maxMapSize))
{
_log.Debug($"GetBoundsWithinWorldAndLandClaim found that the source position was not within a land claim");
return; // source pos was not within a land claim
_log.Warn("World.GetWorldExtent failed when checking for limits; this is not expected and may indicate an error.");
return;
}
_log.Debug($"GetBoundsWithinWorldAndLandClaim returned min: {min}, max: {max}");
_ = ThreadManager.StartCoroutine(OrganizeCoroutine(clrIdx, sourcePos, sourceContainer, min, max));
_log.Debug($"minMapSize: {_minMapSize}, maxMapSize: {_maxMapSize}, actualMapSize: {_maxMapSize - _minMapSize}");

if (TryGetActiveLandClaimPosContaining(source, out var lcbPos))
{
_log.Debug($"Land Claim was found containing {source} (pos: {lcbPos}); clamping to world and land claim coordinates.");
min.x = FastMax(source.x - InboxRange, lcbPos.x - LandClaimRadius, _minMapSize.x);
min.z = FastMax(source.z - InboxRange, lcbPos.z - LandClaimRadius, _minMapSize.z);
min.y = FastMax(source.y - InboxRange, yMin, _minMapSize.y);
max.x = FastMin(source.x + InboxRange, lcbPos.x + LandClaimRadius, _maxMapSize.x);
max.z = FastMin(source.z + InboxRange, lcbPos.z + LandClaimRadius, _maxMapSize.z);
max.y = FastMin(source.y + InboxRange, yMax, _maxMapSize.y);
_log.Debug($"clampedMin: {min}, clampedMax: {max}.");
return;
}

_log.Debug($"Land Claim not found containing {source}; clamping to world coordinates only.");
min.x = Utils.FastMax(source.x - InboxRange, _minMapSize.x);
min.z = Utils.FastMax(source.z - InboxRange, _minMapSize.z);
min.y = FastMax(source.y - InboxRange, yMin, _minMapSize.y);
max.x = Utils.FastMin(source.x + InboxRange, _maxMapSize.x);
max.z = Utils.FastMin(source.z + InboxRange, _maxMapSize.z);
max.y = FastMin(source.y + InboxRange, yMax, _maxMapSize.y);
_log.Debug($"clampedMin: {min}, clampedMax: {max}.");
return;
}

internal static bool TryGetActiveLcbCoordsContainingPos(Vector3i sourcePos, out Vector3i landClaimPos)
internal static bool TryGetActiveLandClaimPosContaining(Vector3i sourcePos, out Vector3i lcbPos)
{
var _world = GameManager.Instance.World;
foreach (var kvp in GameManager.Instance.persistentPlayers.Players)
Expand All @@ -71,53 +100,22 @@ internal static bool TryGetActiveLcbCoordsContainingPos(Vector3i sourcePos, out
{
continue; // this player has been offline too long
}
foreach (var lcb in kvp.Value.GetLandProtectionBlocks())
foreach (var pos in kvp.Value.GetLandProtectionBlocks())
{
if (sourcePos.x >= lcb.x - LandClaimRadius &&
sourcePos.x <= lcb.x + LandClaimRadius &&
sourcePos.z >= lcb.z - LandClaimRadius &&
sourcePos.z <= lcb.z + LandClaimRadius)
if (sourcePos.x >= pos.x - LandClaimRadius &&
sourcePos.x <= pos.x + LandClaimRadius &&
sourcePos.z >= pos.z - LandClaimRadius &&
sourcePos.z <= pos.z + LandClaimRadius)
{
landClaimPos = lcb;
lcbPos = pos;
return true;
}
}
}
landClaimPos = default;
lcbPos = default;
return false;
}

internal static bool IsRoboticInbox(int blockId)
{
return SecureInboxBlockId == blockId || InboxBlockId == blockId;
}

private static bool GetBoundsWithinWorldAndLandClaim(Vector3i source, out Vector3i min, out Vector3i max)
{
min = max = default;
if (!TryGetActiveLcbCoordsContainingPos(source, out var lcb))
{
return false;
}
_log.Debug($"Land Claim containing {source} was found at {lcb}");

if (!GameManager.Instance.World.GetWorldExtent(out var _minMapSize, out var _maxMapSize))
{
_log.Warn("World.GetWorldExtent failed when checking for limits; this is not expected and may indicate an error.");
return false;
}
_log.Debug($"minMapSize: {_minMapSize}, maxMapSize: {_maxMapSize}, actualMapSize: {_maxMapSize - _minMapSize}");

min.x = FastMax(source.x - InboxRange, lcb.x - LandClaimRadius, _minMapSize.x);
min.z = FastMax(source.z - InboxRange, lcb.z - LandClaimRadius, _minMapSize.z);
min.y = FastMax(source.y - InboxRange, yMin, _minMapSize.y);
max.x = FastMin(source.x + InboxRange, lcb.x + LandClaimRadius, _maxMapSize.x);
max.z = FastMin(source.z + InboxRange, lcb.z + LandClaimRadius, _maxMapSize.z);
max.y = FastMin(source.y + InboxRange, yMax, _maxMapSize.y);
_log.Debug($"clampedMin: {min}, clampedMax: {max}");
return true;
}

public static int FastMax(int v1, int v2, int v3)
{
return Utils.FastMax(v1, Utils.FastMax(v2, v3));
Expand All @@ -130,6 +128,10 @@ public static int FastMin(int v1, int v2, int v3)

private static IEnumerator OrganizeCoroutine(int clrIdx, Vector3i sourcePos, TileEntityLootContainer source, Vector3i min, Vector3i max)
{
// TODO: optimize this
// TODO: possibly check at most... 1 slice of x at a time?
// see how much time it will take to yield after each vertical cross-section of x/z at a time
// test by returning entire map for clamped range and see if it halts zombies
Vector3i targetPos;
for (var x = min.x; x <= max.x; x++)
{
Expand Down Expand Up @@ -162,6 +164,11 @@ private static bool VerifyContainer(TileEntity entity, out TileEntityLootContain
&& !IsRoboticInbox(entity.blockValue.Block.blockID);
}

internal static bool IsRoboticInbox(int blockId)
{
return SecureInboxBlockId == blockId || InboxBlockId == blockId;
}

private static void Distribute(TileEntityLootContainer source, TileEntityLootContainer target, Vector3i targetPos)
{
if (target.IsUserAccessing())
Expand Down

0 comments on commit cfa1d03

Please sign in to comment.