Piston movement is now prevented if it encroaches across into territories which have the relevant DenyBuild option set (whether faction territory, safe zone, or war zone). This covers piston extension if it pushes across unacceptable borders or even if the piston head itself would cross over, and also prevents sticky pistons from pulling blocks back across such borders.

There is also a new conf.json option "pistonProtectionThroughDenyBuild" (default true) which can be disabled to turn off piston protection. This option is available due to the (untested) potential that a world with many pistons constantly repeatedly firing could result in additional lag from these piston protection events
This commit is contained in:
Brettflan 2011-07-20 12:22:03 -05:00
parent c79692940e
commit 5686c4db9d
3 changed files with 95 additions and 2 deletions

View File

@ -110,6 +110,8 @@ public class Conf {
public static boolean wildernessBlockTNT = false;
public static boolean wildernessPowerLoss = true;
public static boolean pistonProtectionThroughDenyBuild = true;
public static Set<Material> territoryProtectedMaterials = EnumSet.noneOf(Material.class);
public static Set<Material> territoryDenyUseageMaterials = EnumSet.noneOf(Material.class);
public static Set<Material> territoryProtectedMaterialsWhenOffline = EnumSet.noneOf(Material.class);

View File

@ -143,6 +143,8 @@ public class Factions extends JavaPlugin {
pm.registerEvent(Event.Type.BLOCK_BREAK, this.blockListener, Event.Priority.Normal, this);
pm.registerEvent(Event.Type.BLOCK_DAMAGE, this.blockListener, Event.Priority.Normal, this);
pm.registerEvent(Event.Type.BLOCK_PLACE, this.blockListener, Event.Priority.Normal, this);
pm.registerEvent(Event.Type.BLOCK_PISTON_EXTEND, this.blockListener, Event.Priority.Normal, this);
pm.registerEvent(Event.Type.BLOCK_PISTON_RETRACT, this.blockListener, Event.Priority.Normal, this);
// Register recurring tasks
long saveTicks = 20 * 60 * 30; // Approximately every 30 min

View File

@ -1,5 +1,6 @@
package com.massivecraft.factions.listeners;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
@ -7,6 +8,8 @@ import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockDamageEvent;
import org.bukkit.event.block.BlockListener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import com.massivecraft.factions.Board;
import com.massivecraft.factions.Conf;
@ -58,6 +61,92 @@ public class FactionsBlockListener extends BlockListener {
}
}
@Override
public void onBlockPistonExtend(BlockPistonExtendEvent event) {
if (event.isCancelled() || !Conf.pistonProtectionThroughDenyBuild) {
return;
}
Faction pistonFaction = Board.getFactionAt(new FLocation(event.getBlock()));
// target end-of-the-line empty (air) block which is being pushed into, including if piston itself would extend into air
Block targetBlock = event.getBlock().getRelative(event.getDirection(), event.getLength() + 1);
// if potentially pushing into air in another territory, we need to check it out
if (targetBlock.isEmpty() && !canPistonMoveBlock(pistonFaction, targetBlock.getLocation())) {
event.setCancelled(true);
return;
}
/*
* note that I originally was testing the territory of each affected block, but since I found that pistons can only push
* up to 12 blocks and the width of any territory is 16 blocks, it should be safe (and much more lightweight) to test
* only the final target block as done above
*/
}
@Override
public void onBlockPistonRetract(BlockPistonRetractEvent event) {
// if not a sticky piston, retraction should be fine
if (event.isCancelled() || !event.isSticky() || !Conf.pistonProtectionThroughDenyBuild) {
return;
}
Location targetLoc = event.getRetractLocation();
// if potentially retracted block is just air, no worries
if (targetLoc.getBlock().isEmpty()) {
return;
}
Faction pistonFaction = Board.getFactionAt(new FLocation(event.getBlock()));
if (!canPistonMoveBlock(pistonFaction, targetLoc)) {
event.setCancelled(true);
return;
}
}
private boolean canPistonMoveBlock(Faction pistonFaction, Location target) {
Faction otherFaction = Board.getFactionAt(new FLocation(target));
if (pistonFaction == otherFaction) {
return true;
}
if (otherFaction.isNone()) {
if (!Conf.wildernessDenyBuild) {
return true;
}
return false;
}
else if (otherFaction.isSafeZone()) {
if (!Conf.safeZoneDenyBuild) {
return true;
}
return false;
}
else if (otherFaction.isWarZone()) {
if (!Conf.warZoneDenyBuild) {
return true;
}
return false;
}
boolean areEnemies = pistonFaction.getRelation(otherFaction).isEnemy();
boolean online = otherFaction.hasPlayersOnline();
if (
(online && (areEnemies ? Conf.territoryEnemyDenyBuild : Conf.territoryDenyBuild))
|| (!online && (areEnemies ? Conf.territoryEnemyDenyBuildWhenOffline : Conf.territoryDenyBuildWhenOffline))
) {
return false;
}
return true;
}
public boolean playerCanBuildDestroyBlock(Player player, Block block, String action) {
if (Conf.adminBypassPlayers.contains(player.getName())) {