Skip to content

Commit

Permalink
Version bump to 0.8.7 - fix entity selectors incorrectly blocking sel…
Browse files Browse the repository at this point in the history
…ection when it should allow
  • Loading branch information
3TUSK committed Sep 24, 2024
1 parent e020682 commit ce95191
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 6 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ mod_name=Area Control
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=BSD-3-Clause
# The mod version. See https://semver.org/
mod_version=0.8.6
mod_version=0.8.7
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,17 @@ private static boolean check0(CommandSourceStack sourceStack, Entity e,
String selectFromChild, String selectFromParent,
Supplier<@NotNull Boolean> selectFromChildFallBack,
Supplier<@NotNull Boolean> selectFromParentFallBack) {
var area = AreaManager.INSTANCE.findBy(sourceStack.getLevel(), sourceStack.getPosition());
var startArea = AreaManager.INSTANCE.findBy(sourceStack.getLevel(), sourceStack.getPosition());
// Get the area in which the target entity locates.
// Do note that, EntitySelector can select entities from a different dimension,
// so we must use the level from the target entity.
final var targetArea = AreaManager.INSTANCE.findBy(e.level(), new Vec3(e.xo, e.yo, e.zo));
// If the entity is in the same area as the selector initiator, then it may be selected
if (area == targetArea) {
if (startArea == targetArea) {
return true;
}
// Otherwise, we follow this procedure to determine.
var currentlyChecking = area;
var currentlyChecking = startArea;
// 1. Walk up from the area hierarchy tree, checking if all the parent areas
// allow "selecting entities from child area".
// The walking stops at the area that is common ancestor to both the
Expand All @@ -77,16 +77,18 @@ private static boolean check0(CommandSourceStack sourceStack, Entity e,
// Otherwise, we'd have NPE. This is specifically the case for vanilla
// /tp command.
if (currentlyChecking != null) {
do {
while (!AreaMath.isEnclosing(currentlyChecking, targetArea)) {
currentlyChecking = currentlyChecking.resolveParent();
var result = AreaProperties.getBoolOptional(currentlyChecking, selectFromChild);
if (!result.orElseGet(selectFromChildFallBack)) {
return false;
}
} while (!AreaMath.isEnclosing(currentlyChecking, targetArea));
}
}
// 2. If we are at the target area, then we are done, we can select this entity.
// Else, we have to walk down along the hierarchy tree, to the target area.
// For performance reason, we walk down the hierarchy by "walking up" from the
// target area (which is the smallest) to the common ancestor we found above.
if (currentlyChecking != targetArea) {
var reverseChecking = targetArea;
// 3. For each area that we encounter, we check if it allows "selecting entities
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ public static void setup() {
initAreaManager();
}

/*
* Area overview:
*
* - Area A
* - Child area B
* - Child area C
* - Child area D
* - Child area E
* - Child area F
* - Child area G
* - Child area H
* - Area I
* - Child area J
*/
public static void initAreaManager() {
Area a, b, c, d, e, f, g, h, i, j;
var allAreas = new ArrayList<Area>();
Expand Down Expand Up @@ -104,6 +118,9 @@ public static void initAreaManager() {
d.properties.put(AreaProperties.ALLOW_ENTITY_USE_SELECTOR_FROM_PARENT, true);
d.properties.put(AreaProperties.ALLOW_CB_USE_SELECTOR_FROM_PARENT, true);

i.properties.put(AreaProperties.ALLOW_ENTITY_USE_SELECTOR_FROM_PARENT, false);
j.properties.put(AreaProperties.ALLOW_ENTITY_USE_SELECTOR_FROM_PARENT, true);

var areaRepo = new InMemoryAreaRepository(allAreas);
try {
AreaManager.INSTANCE.init(areaRepo);
Expand Down Expand Up @@ -200,6 +217,29 @@ public void testSelectingByCommandBlockFromMultiLayerNestedAreas() {
Assertions.assertTrue(AreaEntitySelectorChecker.check(commandSrc, this.mockEntity));
}

/**
* Test that a player, who is standing in an area A, can use entity selector to select entities inside area B, where
* <ul>
* <li>Area B is a child area of area A</li>
* <li>Area A sets {@link AreaProperties#ALLOW_ENTITY_USE_SELECTOR_FROM_PARENT}</li> to <code>false</code></li>
* <li>Area B sets {@link AreaProperties#ALLOW_ENTITY_USE_SELECTOR_FROM_PARENT}</li> to <code>true</code></li>
* </ul>
* This test case is named after KunoSayo, who firstly reported that such setup was not working as expected.
*/
@Test
public void testKunoSayoAreaSetup() {
// Create a CommandSourceStack with true source being a mock command block, location is [41.1, 41.1, 41.1] (in area I).
var commandSrc = new CommandSourceStack(this.mockCmdBlock, new Vec3(41.1, 41.1, 41.1), Vec2.ZERO, this.mockLevel, 4, "yinyangshi", Component.literal("KunoSayo"), mockServer, null);
// Position mock entity to [ 42.5, 42.5, 42.5 ] of overworld (in area J)
Mockito.when(this.mockLevel.dimension()).thenReturn(Level.OVERWORLD);
this.mockEntity.xo = 42.5;
this.mockEntity.yo = 42.5;
this.mockEntity.zo = 42.5;
Mockito.when(this.mockEntity.level()).thenReturn(this.mockLevel);
// Verify that the command source can use entity selector to select the mock entity
Assertions.assertTrue(AreaEntitySelectorChecker.check(commandSrc, this.mockEntity));
}

public static Area createArea(String name, String dim, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
var area = new Area();
area.uid = UUID.randomUUID();
Expand Down

0 comments on commit ce95191

Please sign in to comment.