Refactored and fixed fire handling.

- Logic should now be easier to follow
- Less code duplication
- The fire-spread flag, the fire.disable-all-fire-spread and the
  stop/allowfire commands now do the same thing.
- The "High frequency flag" setting is now enforced consistently on all
  parts of the fire-spread flag, not just half of it.
This commit is contained in:
TomyLobo 2013-06-10 20:40:38 +02:00
parent c88052eeb8
commit 722a0b9cfc

View File

@ -39,7 +39,6 @@
import org.bukkit.event.block.BlockFormEvent; import org.bukkit.event.block.BlockFormEvent;
import org.bukkit.event.block.BlockFromToEvent; import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockIgniteEvent; import org.bukkit.event.block.BlockIgniteEvent;
import org.bukkit.event.block.BlockIgniteEvent.IgniteCause;
import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent; import org.bukkit.event.block.BlockPistonRetractEvent;
@ -272,55 +271,80 @@ public void onBlockFromTo(BlockFromToEvent event) {
} }
} }
/**
* Determines whether fire can spread into a block.
*
* @param block The block in question
* @return true if allowed, false otherwise
*/
private boolean isFireSpreadAllowed(Block block) {
final ConfigurationManager cfg = plugin.getGlobalStateManager();
final WorldConfiguration wcfg = cfg.get(block.getWorld());
if (wcfg.disableFireSpread) {
return false;
}
if (wcfg.fireSpreadDisableToggle) {
return false;
}
if (!wcfg.highFreqFlags) {
return true;
}
if (!wcfg.useRegions) {
return true;
}
final Vector pt = toVector(block);
final RegionManager mgr = plugin.getGlobalRegionManager().get(block.getWorld());
final ApplicableRegionSet set = mgr.getApplicableRegions(pt);
return set.allows(DefaultFlag.FIRE_SPREAD);
}
/* /*
* Called when a block gets ignited. * Called when a block gets ignited.
*/ */
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockIgnite(BlockIgniteEvent event) { public void onBlockIgnite(BlockIgniteEvent event) {
IgniteCause cause = event.getCause(); final Block block = event.getBlock();
Block block = event.getBlock(); final World world = block.getWorld();
World world = block.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager(); final ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world); final WorldConfiguration wcfg = cfg.get(world);
if (cfg.activityHaltToggle) { if (cfg.activityHaltToggle) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
boolean isFireSpread = cause == IgniteCause.SPREAD;
if (wcfg.preventLightningFire && cause == IgniteCause.LIGHTNING) { final ApplicableRegionSet set;
event.setCancelled(true);
return; if (wcfg.useRegions) {
Vector pt = toVector(block);
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
set = mgr.getApplicableRegions(pt);
} else {
set = null;
} }
if (wcfg.preventLavaFire && cause == IgniteCause.LAVA) { switch (event.getCause()) {
event.setCancelled(true); case SPREAD:
return; if (!isFireSpreadAllowed(block)) {
} event.setCancelled(true);
return;
}
if (wcfg.disableFireSpread && isFireSpread) { if (wcfg.disableFireSpreadBlocks.size() <= 0) {
event.setCancelled(true); break;
return; }
}
if (wcfg.blockLighter && (cause == IgniteCause.FLINT_AND_STEEL || cause == IgniteCause.FIREBALL) final int x = block.getX();
&& event.getPlayer() != null final int y = block.getY();
&& !plugin.hasPermission(event.getPlayer(), "worldguard.override.lighter")) { final int z = block.getZ();
event.setCancelled(true);
return;
}
if (wcfg.fireSpreadDisableToggle && isFireSpread) {
event.setCancelled(true);
return;
}
if (wcfg.disableFireSpreadBlocks.size() > 0 && isFireSpread) {
int x = block.getX();
int y = block.getY();
int z = block.getZ();
if (wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x, y - 1, z)) if (wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x, y - 1, z))
|| wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x + 1, y, z)) || wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x + 1, y, z))
@ -330,53 +354,92 @@ public void onBlockIgnite(BlockIgniteEvent event) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
}
if (wcfg.useRegions) { break;
Vector pt = toVector(block);
Player player = event.getPlayer();
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
if (player != null && !plugin.getGlobalRegionManager().hasBypass(player, world)) { case LIGHTNING:
LocalPlayer localPlayer = plugin.wrapPlayer(player); if (wcfg.preventLightningFire) {
// this is preliminarily handled in the player listener under handleBlockRightClick
// why it's handled here too, no one knows
if (cause == IgniteCause.FLINT_AND_STEEL || cause == IgniteCause.FIREBALL) {
if (!set.allows(DefaultFlag.LIGHTER)
&& !set.canBuild(localPlayer)
&& !plugin.hasPermission(player, "worldguard.override.lighter")) {
event.setCancelled(true);
return;
}
}
}
if (wcfg.highFreqFlags && isFireSpread
&& !set.allows(DefaultFlag.FIRE_SPREAD)) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
if (wcfg.highFreqFlags && cause == IgniteCause.LAVA if (!wcfg.useRegions) {
&& !set.allows(DefaultFlag.LAVA_FIRE)) { break;
}
if (set.allows(DefaultFlag.LIGHTNING)) {
break;
}
event.setCancelled(true);
return;
case LAVA:
if (wcfg.preventLavaFire) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
if (cause == IgniteCause.FIREBALL && event.getPlayer() == null) { if (!wcfg.useRegions) {
// wtf bukkit, FIREBALL is supposed to be reserved to players break;
if (!set.allows(DefaultFlag.GHAST_FIREBALL)) {
event.setCancelled(true);
return;
}
} }
if (cause == IgniteCause.LIGHTNING && !set.allows(DefaultFlag.LIGHTNING)) { if (!wcfg.highFreqFlags) {
break;
}
if (set.allows(DefaultFlag.LAVA_FIRE)) {
break;
}
event.setCancelled(true);
return;
case FIREBALL:
if (wcfg.useRegions && event.getPlayer() == null && !set.allows(DefaultFlag.GHAST_FIREBALL)) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
/* FALL-THROUGH */
case FLINT_AND_STEEL:
final Player player = event.getPlayer();
if (player == null) {
break;
}
if (wcfg.blockLighter && !plugin.hasPermission(player, "worldguard.override.lighter")) {
event.setCancelled(true);
return;
}
if (!wcfg.useRegions) {
break;
}
if (plugin.getGlobalRegionManager().hasBypass(player, world)) {
break;
}
final LocalPlayer localPlayer = plugin.wrapPlayer(player);
// Lighters are preliminarily handled in the player listener under handleBlockRightClick.
// Why they're handled here too, no one knows
if (set.allows(DefaultFlag.LIGHTER)) {
break;
}
if (set.canBuild(localPlayer)) {
break;
}
if (plugin.hasPermission(player, "worldguard.override.lighter")) {
break;
}
event.setCancelled(true);
return;
} }
} }
@ -385,26 +448,16 @@ public void onBlockIgnite(BlockIgniteEvent event) {
*/ */
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockBurn(BlockBurnEvent event) { public void onBlockBurn(BlockBurnEvent event) {
ConfigurationManager cfg = plugin.getGlobalStateManager(); final ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); final WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
if (cfg.activityHaltToggle) { if (cfg.activityHaltToggle) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
if (wcfg.disableFireSpread) {
event.setCancelled(true);
return;
}
if (wcfg.fireSpreadDisableToggle) {
event.setCancelled(true);
return;
}
if (wcfg.disableFireSpreadBlocks.size() > 0) { if (wcfg.disableFireSpreadBlocks.size() > 0) {
Block block = event.getBlock(); final Block block = event.getBlock();
if (wcfg.disableFireSpreadBlocks.contains(block.getTypeId())) { if (wcfg.disableFireSpreadBlocks.contains(block.getTypeId())) {
event.setCancelled(true); event.setCancelled(true);
@ -417,17 +470,9 @@ public void onBlockBurn(BlockBurnEvent event) {
return; return;
} }
if (wcfg.useRegions) { if (!isFireSpreadAllowed(event.getBlock())) {
Block block = event.getBlock(); event.setCancelled(true);
Vector pt = toVector(block); return;
RegionManager mgr = plugin.getGlobalRegionManager().get(block.getWorld());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
if (!set.allows(DefaultFlag.FIRE_SPREAD)) {
event.setCancelled(true);
return;
}
} }
} }