package mhfc.net.common.world.area; import java.util.Objects; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import mhfc.net.common.quests.world.IQuestAreaSpawnController; import mhfc.net.common.world.controller.CornerPosition; import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.BlockEvent.BreakEvent; import net.minecraftforge.event.world.BlockEvent.PlaceEvent; public abstract class AreaAdapter implements IArea { protected static enum State { RAW, INITIALIZED, ACQUIRED; } protected final World world; protected AreaConfiguration config; protected IWorldView worldView; protected State state; protected IQuestAreaSpawnController spawnController; /** * Constructs and initializes the area */ public AreaAdapter(World world, AreaConfiguration config) { this.world = Objects.requireNonNull(world); this.config = Objects.requireNonNull(config); this.worldView = new DisplacedView(config.getPosition(), config, world); this.spawnController = initializeSpawnController(); this.state = State.INITIALIZED; } protected abstract IQuestAreaSpawnController initializeSpawnController(); protected CornerPosition getChunkPosition() { return this.config.getPosition(); } protected boolean isAccessLegal() { return state != State.RAW; } @Override public IWorldView getWorldView() { if (!isAccessLegal()) { throw new IllegalStateException("Area is not yet initialized"); } return worldView; } @Override public void onAcquire() { if (state != State.INITIALIZED) { throw new IllegalStateException("Area is not acquireable"); } MinecraftForge.EVENT_BUS.register(this); state = State.ACQUIRED; } @Override public void onDismiss() { if (state != State.ACQUIRED) { throw new IllegalStateException("Area is not dismissable"); } MinecraftForge.EVENT_BUS.unregister(this); state = State.INITIALIZED; } @Override public IQuestAreaSpawnController getSpawnController() { return spawnController; } private boolean isInArea(double xCoord, double zCoord) { CornerPosition chunkPos = getChunkPosition(); return xCoord / 16 >= chunkPos.posX && xCoord / 16 < chunkPos.posX + config.getChunkSizeX() && zCoord / 16 >= chunkPos.posY && zCoord / 16 < chunkPos.posY + config.getChunkSizeZ(); } private boolean isInArea(BlockEvent event) { if (event.world != world) { return false; } return isInArea(event.x, event.z); } @SubscribeEvent public void onBlockBreakEvent(BreakEvent event) { if (!isInArea(event)) { return; } event.setCanceled(true); } @SubscribeEvent public void onBlockPlaceEvent(PlaceEvent event) { // FIXME allow the placement of the bbq item or stasis traps for example but revert them on leaving the area if (!isInArea(event)) { return; } event.setCanceled(true); } }