diff --git a/src/main/java/emu/grasscutter/command/commands/SetPropCommand.java b/src/main/java/emu/grasscutter/command/commands/SetPropCommand.java index 0cf0dc1c5..5e5e779ce 100644 --- a/src/main/java/emu/grasscutter/command/commands/SetPropCommand.java +++ b/src/main/java/emu/grasscutter/command/commands/SetPropCommand.java @@ -12,6 +12,7 @@ import emu.grasscutter.server.packet.send.PacketScenePointUnlockNotify; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.IntStream; @Command( @@ -107,6 +108,7 @@ public final class SetPropCommand implements CommandHandler { case "on", "true" -> 1; case "off", "false" -> 0; case "toggle" -> -1; + case "all" -> -2; default -> Integer.parseInt(valueStr); }; } catch (NumberFormatException ignored) { @@ -126,7 +128,7 @@ public final class SetPropCommand implements CommandHandler { sender, targetPlayer, prop.pseudoProp, value); case SET_OPENSTATE -> this.setOpenState(targetPlayer, value, 1); case UNSET_OPENSTATE -> this.setOpenState(targetPlayer, value, 0); - case UNLOCK_MAP -> unlockMap(targetPlayer); + case UNLOCK_MAP -> unlockMap(targetPlayer, value); default -> targetPlayer.setProperty(prop.prop, value); }; @@ -217,13 +219,30 @@ public final class SetPropCommand implements CommandHandler { return true; } - private boolean unlockMap(Player targetPlayer) { + private boolean unlockMap(Player targetPlayer, int value) { // Unlock. GameData.getScenePointsPerScene() .forEach( (sceneId, scenePoints) -> { - // Unlock trans points. - targetPlayer.getUnlockedScenePoints(sceneId).addAll(scenePoints); + if (value == -2) { + // Unlock trans points. + targetPlayer.getUnlockedScenePoints(sceneId).addAll(scenePoints); + } else { + var scenePointsBackup = new CopyOnWriteArrayList<>(scenePoints); + for (var p : scenePointsBackup) { + var scenePointEentry = GameData.getScenePointEntryById(sceneId, p); + var pointData = scenePointEentry.getPointData(); + + boolean forbidSimpleUnlock = pointData.isForbidSimpleUnlock(); + boolean sceneBuildingPointLocked = + pointData.getType().equals("SceneBuildingPoint") && !pointData.isUnlocked(); + + if (forbidSimpleUnlock || sceneBuildingPointLocked) scenePointsBackup.remove(p); + } + + // Unlock trans points. + targetPlayer.getUnlockedScenePoints(sceneId).addAll(scenePointsBackup); + } // Unlock map areas. targetPlayer.getUnlockedSceneAreas(sceneId).addAll(sceneAreas); diff --git a/src/main/java/emu/grasscutter/data/common/PointData.java b/src/main/java/emu/grasscutter/data/common/PointData.java index 892300d05..b3ffddc13 100644 --- a/src/main/java/emu/grasscutter/data/common/PointData.java +++ b/src/main/java/emu/grasscutter/data/common/PointData.java @@ -19,6 +19,8 @@ public final class PointData { @Getter private Position pos; @Getter private Position rot; @Getter private Position size; + @Getter private boolean forbidSimpleUnlock; + @Getter private boolean unlocked; @SerializedName( value = "dungeonIds",