Have other flags override BUILD but not the other way like in WG 5.

This commit is contained in:
sk89q 2014-08-29 12:17:17 -07:00
parent 096981bd27
commit 01892b609f
2 changed files with 90 additions and 28 deletions

View File

@ -105,6 +105,78 @@ public ApplicableRegionSet getApplicableRegions(Location location) {
}
}
/**
* Returns true if the BUILD flag allows the action in the location, but it
* can be overridden by a list of other flags. The BUILD flag will not
* override the other flags, but the other flags can override BUILD. If
* neither BUILD or any of the flags permit the action, then false will
* be returned.
*
* <p>Use this method when checking flags that are related to build
* protection. For example, lighting fire in a region should not be
* permitted unless the player is a member of the region or the
* LIGHTER flag allows it. However, the LIGHTER flag should be able
* to allow lighting fires even if BUILD is set to DENY.</p>
*
* <p>How this method works (BUILD can be overridden by other flags but
* not the other way around) is inconsistent, but it's required for
* legacy reasons.</p>
*
* <p>This method does not check the region bypass permission. That must
* be done by the calling code.</p>
*
* @param location the location
* @param player an optional player, which would be used to determine the region group to apply
* @param flag the flag
* @return true if the result was {@code ALLOW}
* @see RegionResultSet#queryValue(RegionAssociable, Flag)
*/
public boolean testBuild(Location location, Player player, StateFlag... flag) {
if (flag.length == 0) {
return testState(location, player, DefaultFlag.BUILD);
}
return StateFlag.test(StateFlag.combine(
StateFlag.denyToNone(queryState(location, player, DefaultFlag.BUILD)),
queryState(location, player, flag)));
}
/**
* Returns true if the BUILD flag allows the action in the location, but it
* can be overridden by a list of other flags. The BUILD flag will not
* override the other flags, but the other flags can override BUILD. If
* neither BUILD or any of the flags permit the action, then false will
* be returned.
*
* <p>Use this method when checking flags that are related to build
* protection. For example, lighting fire in a region should not be
* permitted unless the player is a member of the region or the
* LIGHTER flag allows it. However, the LIGHTER flag should be able
* to allow lighting fires even if BUILD is set to DENY.</p>
*
* <p>How this method works (BUILD can be overridden by other flags but
* not the other way around) is inconsistent, but it's required for
* legacy reasons.</p>
*
* <p>This method does not check the region bypass permission. That must
* be done by the calling code.</p>
*
* @param location the location
* @param associable an optional associable
* @param flag the flag
* @return true if the result was {@code ALLOW}
* @see RegionResultSet#queryValue(RegionAssociable, Flag)
*/
public boolean testBuild(Location location, RegionAssociable associable, StateFlag... flag) {
if (flag.length == 0) {
return testState(location, associable, DefaultFlag.BUILD);
}
return StateFlag.test(StateFlag.combine(
StateFlag.denyToNone(queryState(location, associable, DefaultFlag.BUILD)),
queryState(location, associable, flag)));
}
/**
* Test whether the (effective) value for a list of state flags equals
* {@code ALLOW}.

View File

@ -174,13 +174,12 @@ public boolean apply(Location target) {
/* Flint and steel, fire charge, etc. */
if (type == Material.FIRE) {
canPlace = query.testState(target, associable, DefaultFlag.BUILD, DefaultFlag.BLOCK_PLACE)
|| query.testState(target, associable, DefaultFlag.LIGHTER);
canPlace = query.testBuild(target, associable, DefaultFlag.BLOCK_PLACE, DefaultFlag.LIGHTER);
what = "place fire";
/* Everything else */
} else {
canPlace = query.testState(target, associable, DefaultFlag.BUILD, DefaultFlag.BLOCK_PLACE);
canPlace = query.testBuild(target, associable, DefaultFlag.BLOCK_PLACE);
what = "place that block";
}
@ -212,13 +211,12 @@ public boolean apply(Location target) {
/* TNT */
if (event.getCause().find(EntityType.PRIMED_TNT, EntityType.PRIMED_TNT) != null) {
canBreak = query.testState(target, associable, DefaultFlag.BUILD, DefaultFlag.BLOCK_BREAK)
|| query.testState(target, associable, DefaultFlag.TNT);
canBreak = query.testBuild(target, associable, DefaultFlag.BLOCK_BREAK, DefaultFlag.TNT);
what = "dynamite blocks";
/* Everything else */
} else {
canBreak = query.testState(target, associable, DefaultFlag.BUILD, DefaultFlag.BLOCK_BREAK);
canBreak = query.testBuild(target, associable, DefaultFlag.BLOCK_BREAK);
what = "break that block";
}
@ -250,26 +248,22 @@ public boolean apply(Location target) {
/* Inventory */
if (Materials.isInventoryBlock(type)) {
canUse = query.testState(target, associable, DefaultFlag.BUILD)
|| query.testState(target, associable, DefaultFlag.USE, DefaultFlag.CHEST_ACCESS);
canUse = query.testBuild(target, associable, DefaultFlag.USE, DefaultFlag.CHEST_ACCESS);
what = "open that";
/* Beds */
} else if (type == Material.BED_BLOCK) {
canUse = query.testState(target, associable, DefaultFlag.BUILD)
|| query.testState(target, associable, DefaultFlag.USE, DefaultFlag.SLEEP);
canUse = query.testBuild(target, associable, DefaultFlag.USE, DefaultFlag.SLEEP);
what = "sleep";
/* TNT */
} else if (type == Material.TNT) {
canUse = query.testState(target, associable, DefaultFlag.BUILD)
|| query.testState(target, associable, DefaultFlag.TNT);
canUse = query.testBuild(target, associable, DefaultFlag.TNT);
what = "use explosives";
/* Everything else */
} else {
canUse = query.testState(target, associable, DefaultFlag.BUILD)
|| query.testState(target, associable, DefaultFlag.USE);
canUse = query.testBuild(target, associable, DefaultFlag.USE);
what = "use that";
}
@ -299,19 +293,17 @@ public void onSpawnEntity(SpawnEntityEvent event) {
/* Vehicles */
if (Entities.isVehicle(type)) {
canSpawn = query.testState(target, associable, DefaultFlag.BUILD)
|| query.testState(target, associable, DefaultFlag.PLACE_VEHICLE);
canSpawn = query.testBuild(target, associable, DefaultFlag.PLACE_VEHICLE);
what = "place vehicles";
/* Item pickup */
} else if (event.getEntity() instanceof Item) {
canSpawn = query.testState(target, associable, DefaultFlag.BUILD)
|| query.testState(target, associable, DefaultFlag.ITEM_DROP);
canSpawn = query.testBuild(target, associable, DefaultFlag.ITEM_DROP);
what = "drop items";
/* Everything else */
} else {
canSpawn = query.testState(target, associable, DefaultFlag.BUILD);
canSpawn = query.testBuild(target, associable);
if (event.getEntity() instanceof Item) {
what = "drop items";
@ -341,19 +333,17 @@ public void onDestroyEntity(DestroyEntityEvent event) {
/* Vehicles */
if (Entities.isVehicle(type)) {
canDestroy = query.testState(target, associable, DefaultFlag.BUILD)
|| query.testState(target, associable, DefaultFlag.DESTROY_VEHICLE);
canDestroy = query.testBuild(target, associable, DefaultFlag.DESTROY_VEHICLE);
what = "break vehicles";
/* Item pickup */
} else if (event.getEntity() instanceof Item) {
canDestroy = query.testState(target, associable, DefaultFlag.BUILD)
|| query.testState(target, associable, DefaultFlag.ITEM_PICKUP);
canDestroy = query.testBuild(target, associable, DefaultFlag.ITEM_PICKUP);
what = "pick up items";
/* Everything else */
} else {
canDestroy = query.testState(target, associable, DefaultFlag.BUILD);
canDestroy = query.testBuild(target, associable);
what = "break things";
}
@ -382,7 +372,7 @@ public void onUseEntity(UseEntityEvent event) {
/* Everything else */
} else {
canUse = query.testState(target, associable, DefaultFlag.BUILD) || query.testState(target, associable, DefaultFlag.USE);
canUse = query.testBuild(target, associable, DefaultFlag.USE);
what = "use that";
}
@ -414,7 +404,7 @@ public void onDamageEntity(DamageEntityEvent event) {
} else if (event.getEntity() instanceof Player && (attacker = event.getCause().getFirstPlayer()) != null && !attacker.equals(event.getEntity())) {
Player defender = (Player) event.getEntity();
canDamage = (query.testState(target, associable, DefaultFlag.BUILD) || query.testState(target, associable, DefaultFlag.PVP))
canDamage = query.testBuild(target, associable, DefaultFlag.PVP)
&& query.queryState(attacker.getLocation(), attacker, DefaultFlag.PVP) != State.DENY;
// Fire the disallow PVP event
@ -426,7 +416,7 @@ public void onDamageEntity(DamageEntityEvent event) {
/* Everything else */
} else {
canDamage = query.testState(target, associable, DefaultFlag.BUILD) || query.testState(target, associable, DefaultFlag.USE);
canDamage = query.testBuild(target, associable, DefaultFlag.USE);
what = "hit that";
}
@ -446,7 +436,7 @@ public void onVehicleExit(VehicleExitEvent event) {
if (!isWhitelisted(Cause.create(player), vehicle.getWorld())) {
RegionQuery query = getPlugin().getRegionContainer().createQuery();
Location location = vehicle.getLocation();
if (!query.testState(location, player, DefaultFlag.BUILD) && !query.testState(location, player, DefaultFlag.USE)) {
if (!query.testBuild(location, player, DefaultFlag.USE)) {
long now = System.currentTimeMillis();
Long lastTime = WGMetadata.getIfPresent(player, DISEMBARK_MESSAGE_KEY, Long.class);
if (lastTime == null || now - lastTime >= LAST_MESSAGE_DELAY) {