Search in sources :

Example 1 with Pair

use of com.github.jikoo.planarwrappers.tuple.Pair in project Easterlyn by Easterlyn.

the class EasterlynMachines method createMachine.

/**
 * Creates data for a new Machine. Note that this does not place the machine's physical structure.
 *
 * @param key the central block of the machine
 * @param machine the Machine to build
 * @param owner the owner of the machine
 * @param direction the direction the machine is facing
 * @return the
 */
@Nullable
private Pair<Machine, ConfigurationSection> createMachine(@NotNull Block key, @NotNull Machine machine, @NotNull UUID owner, @NotNull Direction direction) {
    if (getConfig().getStringList("+disabled-worlds+").contains(key.getWorld().getName())) {
        return null;
    }
    ConfigurationSection section = getConfig().createSection(pathFromLoc(key.getLocation()));
    section.set("type", machine.getName().toLowerCase());
    section.set("owner", owner.toString());
    section.set("direction", direction.name());
    machine.getShape().getBuildLocations(key, direction).forEach((block, data) -> {
        blocksToKeys.put(block, key);
        keysToBlocks.put(key, block);
    });
    return new Pair<>(machine, section);
}
Also used : ConfigurationSection(org.bukkit.configuration.ConfigurationSection) Pair(com.github.jikoo.planarwrappers.tuple.Pair) Nullable(org.jetbrains.annotations.Nullable)

Example 2 with Pair

use of com.github.jikoo.planarwrappers.tuple.Pair in project Easterlyn by Easterlyn.

the class EasterlynEffects method getEffectFromLore.

/**
 * Gets the Effect and level represented by a String in an ItemStack's lore.
 *
 * @param lore the String
 * @param ignoreCase if case should be ignored when matching Effect
 */
@Nullable
public Pair<Effect, Integer> getEffectFromLore(@NotNull String lore, boolean ignoreCase) {
    Matcher match = effectPattern.matcher(lore);
    if (!match.find()) {
        return null;
    }
    lore = ChatColor.stripColor(match.group(1));
    Effect effect = null;
    if (effects.containsKey(lore)) {
        effect = effects.get(lore);
    } else {
        if (!ignoreCase) {
            return null;
        }
        for (Map.Entry<String, Effect> entry : effects.entrySet()) {
            if (entry.getKey().equalsIgnoreCase(lore)) {
                effect = entry.getValue();
                break;
            }
        }
        if (effect == null) {
            return null;
        }
    }
    try {
        return new Pair<>(effect, NumberUtil.intFromRoman(match.group(2)));
    } catch (NumberFormatException e) {
        return null;
    }
}
Also used : Matcher(java.util.regex.Matcher) Effect(com.easterlyn.effect.Effect) HashMap(java.util.HashMap) Map(java.util.Map) Pair(com.github.jikoo.planarwrappers.tuple.Pair) Nullable(org.jetbrains.annotations.Nullable)

Example 3 with Pair

use of com.github.jikoo.planarwrappers.tuple.Pair in project Easterlyn by Easterlyn.

the class EasterlynMachines method onEnable.

@Override
public void onEnable() {
    saveDefaultConfig();
    new Reflections("com.easterlyn.machine", getClassLoader()).getSubTypesOf(Machine.class).stream().filter(clazz -> !Modifier.isAbstract(clazz.getModifiers())).forEach(clazz -> {
        Constructor<? extends Machine> constructor;
        Machine machine;
        try {
            constructor = clazz.getConstructor(this.getClass());
            machine = constructor.newInstance(this);
        } catch (ReflectiveOperationException e) {
            getLogger().severe("Unable to load machine " + clazz.getName());
            e.printStackTrace();
            return;
        }
        nameRegistry.put(machine.getClass().getSimpleName().toLowerCase(), machine);
        nameRegistry.put(machine.getName().toLowerCase(), machine);
        iconRegistry.put(machine.getUniqueDrop(), machine);
    });
    Event.register(BlockPlaceEvent.class, event -> {
        Player player = event.getPlayer();
        Pair<Machine, ConfigurationSection> pair = getMachine(event.getBlock());
        if (pair != null) {
            // Block registered as part of a machine. Most likely removed by explosion or similar.
            // Prevents place PGO as diamond block, blow up PGO, place and break dirt in PGO's
            // location to unregister, wait for CreeperHeal to regenerate diamond block for profit.
            event.setCancelled(true);
            player.sendMessage("machines.noTouch");
            // fire a reportable event and repair.
            if (exploded.get(event.getBlock()) == null) {
                pair.getLeft().reassemble(pair.getRight());
                ReportableEvent.call(String.format("Repairing broken %s at %s %s %s after internal placement by %s", pair.getLeft().getName(), event.getBlock().getX(), event.getBlock().getY(), event.getBlock().getZ(), event.getPlayer().getName()));
            }
            return;
        }
        // Machine place logic
        for (Map.Entry<ItemStack, Machine> entry : iconRegistry.entrySet()) {
            if (entry.getKey().isSimilar(event.getItemInHand())) {
                pair = createMachine(event.getBlock(), entry.getValue(), event.getPlayer().getUniqueId(), Direction.getFacingDirection(event.getPlayer()));
                if (pair == null) {
                    event.setCancelled(true);
                    return;
                }
                if (pair.getLeft().failedAssembly(pair.getRight())) {
                    event.setCancelled(true);
                }
                if (!event.isCancelled() && player.getGameMode() != GameMode.CREATIVE) {
                    if (player.getInventory().getItemInMainHand().equals(event.getItemInHand())) {
                        player.getInventory().setItemInMainHand(ItemUtil.decrement(event.getItemInHand(), 1));
                    } else {
                        player.getInventory().setItemInOffHand(ItemUtil.decrement(event.getItemInHand(), 1));
                    }
                }
                event.setCancelled(true);
                break;
            }
        }
    }, this, EventPriority.HIGHEST);
    hookCreeperHeal();
    // Machine event handlers
    Event.register(PlayerInteractEvent.class, event -> {
        if (event.getClickedBlock() == null) {
            return;
        }
        Pair<Machine, ConfigurationSection> machine = getMachine(event.getClickedBlock());
        if (machine != null) {
            machine.getLeft().handleInteract(event, machine.getRight());
        }
    }, this, EventPriority.LOW);
    Event.register(InventoryMoveItemEvent.class, event -> {
        InventoryHolder inventoryHolder = event.getDestination().getHolder();
        // For now, sending inv is not checked, as no machines require it.
        if (inventoryHolder instanceof BlockState) {
            Pair<Machine, ConfigurationSection> pair = getMachine(((BlockState) inventoryHolder).getBlock());
            if (pair != null) {
                pair.getLeft().handleHopperMoveItem(event, pair.getRight());
            }
        }
    }, this, EventPriority.LOW);
    Event.register(InventoryPickupItemEvent.class, event -> {
        InventoryHolder inventoryHolder = event.getInventory().getHolder();
        // For now, sending inv is not checked, as no machines require it.
        if (inventoryHolder instanceof BlockState) {
            Pair<Machine, ConfigurationSection> pair = getMachine(((BlockState) inventoryHolder).getBlock());
            if (pair != null) {
                pair.getLeft().handleHopperPickupItem(event, pair.getRight());
            }
        }
    }, this, EventPriority.LOW);
    registerInventoryEvent(InventoryClickEvent.class, machine -> machine::handleClick);
    registerInventoryEvent(InventoryDragEvent.class, machine -> machine::handleDrag);
    registerInventoryEvent(InventoryOpenEvent.class, machine -> machine::handleOpen);
    registerInventoryEvent(InventoryCloseEvent.class, machine -> machine::handleClose);
    Event.register(InventoryCloseEvent.class, event -> {
        if (event.getView().getTopInventory() instanceof MerchantInventory) {
            merchants.remove(((MerchantInventory) event.getView().getTopInventory()).getMerchant());
        }
    }, this, EventPriority.HIGH);
    Event.register(TradeSelectEvent.class, event -> {
        Pair<Machine, ConfigurationSection> machineData = merchants.get(event.getMerchant());
        if (machineData != null) {
            machineData.getLeft().selectTrade(event, machineData.getRight());
        }
    }, this);
    Event.register(BlockPistonExtendEvent.class, event -> {
        if (isMachine(event.getBlock()) || event.getBlocks().stream().anyMatch(this::isMachine)) {
            event.setCancelled(true);
        }
    }, this, EventPriority.LOW);
    Event.register(BlockPistonRetractEvent.class, event -> {
        if (isMachine(event.getBlock()) || event.getBlocks().stream().anyMatch(this::isMachine)) {
            event.setCancelled(true);
        }
    }, this, EventPriority.LOW);
    Event.register(PlayerBucketEmptyEvent.class, event -> {
        if (isMachine(event.getBlockClicked().getRelative(event.getBlockFace()))) {
            // If we do end up creating a lava well etc. this will need to be added to an event.
            event.setCancelled(true);
        }
    }, this, EventPriority.LOW);
    Consumer<PlayerBucketEvent> bucketConsumer = event -> {
        if (isMachine(event.getBlockClicked().getRelative(event.getBlockFace()))) {
            event.setCancelled(true);
        }
    };
    Event.register(PlayerBucketEmptyEvent.class, bucketConsumer::accept, this, EventPriority.LOW);
    Event.register(PlayerBucketFillEvent.class, bucketConsumer::accept, this, EventPriority.LOW);
    registerBlockEvent(BlockBreakEvent.class, machine -> machine::handleBreak);
    registerBlockEvent(BlockFadeEvent.class, machine -> machine::handleFade);
    registerBlockEvent(BlockFromToEvent.class, machine -> machine::handleFromTo);
    registerBlockEvent(BlockIgniteEvent.class, machine -> machine::handleIgnite);
    registerBlockEvent(BlockSpreadEvent.class, machine -> machine::handleSpread);
    // Prevent all external machine manipulation
    Event.register(BlockPhysicsEvent.class, event -> {
        if (isMachine(event.getBlock())) {
            event.setCancelled(true);
        }
    }, this);
    Event.register(EntityChangeBlockEvent.class, event -> {
        if (isMachine(event.getBlock())) {
            event.setCancelled(true);
        }
    }, this);
    Event.register(ChunkLoadEvent.class, event -> getServer().getScheduler().runTask(this, () -> loadChunkMachines(event.getChunk())), this);
    // TODO periodic save system (timer triggered by chunk unload?)
    Event.register(ChunkUnloadEvent.class, event -> getServer().getScheduler().runTask(this, () -> unloadChunkMachines(event.getChunk())), this);
    for (World world : getServer().getWorlds()) {
        if (getConfig().getStringList("+disabled-worlds+").contains(world.getName())) {
            continue;
        }
        for (Chunk chunk : world.getLoadedChunks()) {
            loadChunkMachines(chunk);
        }
    }
    RegisteredServiceProvider<EasterlynCore> registration = getServer().getServicesManager().getRegistration(EasterlynCore.class);
    if (registration != null) {
        register(registration.getProvider());
    }
    Event.register(PluginEnableEvent.class, pluginEnableEvent -> {
        if (pluginEnableEvent.getPlugin() instanceof EasterlynCore) {
            register((EasterlynCore) pluginEnableEvent.getPlugin());
        }
    }, this);
}
Also used : BlockPistonExtendEvent(org.bukkit.event.block.BlockPistonExtendEvent) Arrays(java.util.Arrays) InventoryEvent(org.bukkit.event.inventory.InventoryEvent) TradeSelectEvent(org.bukkit.event.inventory.TradeSelectEvent) ChunkUnloadEvent(org.bukkit.event.world.ChunkUnloadEvent) ConfigurationSection(org.bukkit.configuration.ConfigurationSection) Player(org.bukkit.entity.Player) Reflections(org.reflections.Reflections) Inventory(org.bukkit.inventory.Inventory) Merchant(org.bukkit.inventory.Merchant) CreeperConfig(com.nitnelave.CreeperHeal.config.CreeperConfig) Block(org.bukkit.block.Block) BlockPistonRetractEvent(org.bukkit.event.block.BlockPistonRetractEvent) Location(org.bukkit.Location) World(org.bukkit.World) PluginEnableEvent(org.bukkit.event.server.PluginEnableEvent) Map(java.util.Map) Chunk(org.bukkit.Chunk) BlockEvent(org.bukkit.event.block.BlockEvent) BlockPlaceEvent(org.bukkit.event.block.BlockPlaceEvent) Bukkit(org.bukkit.Bukkit) BlockPhysicsEvent(org.bukkit.event.block.BlockPhysicsEvent) BlockSpreadEvent(org.bukkit.event.block.BlockSpreadEvent) Machine(com.easterlyn.machine.Machine) Collection(java.util.Collection) Set(java.util.Set) InventoryClickEvent(org.bukkit.event.inventory.InventoryClickEvent) CHBlockHealEvent(com.nitnelave.CreeperHeal.events.CHBlockHealEvent) InventoryDragEvent(org.bukkit.event.inventory.InventoryDragEvent) Pair(com.github.jikoo.planarwrappers.tuple.Pair) UUID(java.util.UUID) EntityType(org.bukkit.entity.EntityType) BlockIgniteEvent(org.bukkit.event.block.BlockIgniteEvent) PlayerBucketFillEvent(org.bukkit.event.player.PlayerBucketFillEvent) ItemStack(org.bukkit.inventory.ItemStack) JavaPlugin(org.bukkit.plugin.java.JavaPlugin) Nullable(org.jetbrains.annotations.Nullable) Event(com.github.jikoo.planarwrappers.event.Event) InventoryOpenEvent(org.bukkit.event.inventory.InventoryOpenEvent) Modifier(java.lang.reflect.Modifier) BlockUtil(com.easterlyn.util.BlockUtil) BlockMultimap(com.github.jikoo.planarwrappers.collections.BlockMultimap) EntityExplodeEvent(org.bukkit.event.entity.EntityExplodeEvent) NotNull(org.jetbrains.annotations.NotNull) InventoryPickupItemEvent(org.bukkit.event.inventory.InventoryPickupItemEvent) BlockMap(com.github.jikoo.planarwrappers.collections.BlockMap) HashMap(java.util.HashMap) Coords(com.github.jikoo.planarwrappers.util.Coords) InventoryCloseEvent(org.bukkit.event.inventory.InventoryCloseEvent) BlockFadeEvent(org.bukkit.event.block.BlockFadeEvent) Constructor(java.lang.reflect.Constructor) Function(java.util.function.Function) GameMode(org.bukkit.GameMode) EntityChangeBlockEvent(org.bukkit.event.entity.EntityChangeBlockEvent) InventoryMoveItemEvent(org.bukkit.event.inventory.InventoryMoveItemEvent) ChunkLoadEvent(org.bukkit.event.world.ChunkLoadEvent) BiConsumer(java.util.function.BiConsumer) PlayerInteractEvent(org.bukkit.event.player.PlayerInteractEvent) ItemUtil(com.easterlyn.util.inventory.ItemUtil) Direction(com.github.jikoo.planarwrappers.world.Direction) Iterator(java.util.Iterator) ReportableEvent(com.easterlyn.event.ReportableEvent) BlockState(org.bukkit.block.BlockState) BlockBreakEvent(org.bukkit.event.block.BlockBreakEvent) Consumer(java.util.function.Consumer) InventoryHolder(org.bukkit.inventory.InventoryHolder) PlayerBucketEmptyEvent(org.bukkit.event.player.PlayerBucketEmptyEvent) EventPriority(org.bukkit.event.EventPriority) PlayerBucketEvent(org.bukkit.event.player.PlayerBucketEvent) Collections(java.util.Collections) RegisteredServiceProvider(org.bukkit.plugin.RegisteredServiceProvider) BlockFromToEvent(org.bukkit.event.block.BlockFromToEvent) MerchantInventory(org.bukkit.inventory.MerchantInventory) Player(org.bukkit.entity.Player) MerchantInventory(org.bukkit.inventory.MerchantInventory) PlayerBucketEvent(org.bukkit.event.player.PlayerBucketEvent) World(org.bukkit.World) Chunk(org.bukkit.Chunk) Machine(com.easterlyn.machine.Machine) BlockState(org.bukkit.block.BlockState) ItemStack(org.bukkit.inventory.ItemStack) Map(java.util.Map) BlockMap(com.github.jikoo.planarwrappers.collections.BlockMap) HashMap(java.util.HashMap) InventoryHolder(org.bukkit.inventory.InventoryHolder) Reflections(org.reflections.Reflections) ConfigurationSection(org.bukkit.configuration.ConfigurationSection)

Example 4 with Pair

use of com.github.jikoo.planarwrappers.tuple.Pair in project Easterlyn by Easterlyn.

the class EasterlynMachines method getMachine.

/**
 * Gets a Machine by Block.
 *
 * @param block the Block
 * @return the Machine or null if the Block is not part of a Machine
 * @throws IllegalStateException if the Machine is malformed
 */
@Nullable
private Pair<Machine, ConfigurationSection> getMachine(@NotNull Block block) throws IllegalStateException {
    Block key = blocksToKeys.get(block);
    if (key == null) {
        return null;
    }
    ConfigurationSection section = getConfig().getConfigurationSection(pathFromLoc(key.getLocation()));
    if (section == null) {
        throw new IllegalStateException("No ConfigurationSection available for stored key block!");
    }
    String type = section.getString("type");
    Machine machine = nameRegistry.get(type);
    if (machine == null) {
        throw new IllegalStateException(String.format("Invalid machine type specified in ConfigurationSection: %s", type));
    }
    return new Pair<>(machine, section);
}
Also used : Block(org.bukkit.block.Block) Machine(com.easterlyn.machine.Machine) ConfigurationSection(org.bukkit.configuration.ConfigurationSection) Pair(com.github.jikoo.planarwrappers.tuple.Pair) Nullable(org.jetbrains.annotations.Nullable)

Example 5 with Pair

use of com.github.jikoo.planarwrappers.tuple.Pair in project Easterlyn by Easterlyn.

the class EasterlynMachines method loadMachine.

/**
 * Loads a machine from the given ConfigurationSection.
 *
 * @param key the machine's key location or null if it is to be parsed from storage
 * @param storage the ConfigurationSection used to store the machine data
 * @return a Pair containing the Machine and its corresponding data
 * @throws IllegalArgumentException if the provided ConfigurationSection cannot be used to load a
 *     Machine.
 */
@NotNull
private Pair<Machine, ConfigurationSection> loadMachine(@Nullable Block key, @NotNull ConfigurationSection storage) throws IllegalArgumentException {
    if (storage.getCurrentPath() == null) {
        throw new IllegalArgumentException("Machine storage must be a ConfigurationSection stored at its location.");
    }
    if (key == null) {
        key = locFromPath(storage.getCurrentPath()).getBlock();
    }
    if (getConfig().getStringList("+disabled-worlds+").contains(key.getWorld().getName())) {
        throw new IllegalArgumentException("Invalid machine at " + storage.getCurrentPath());
    }
    Machine machine = nameRegistry.get(storage.getString("type"));
    if (machine == null) {
        throw new IllegalArgumentException("Invalid machine at " + storage.getCurrentPath());
    }
    for (Block block : machine.getShape().getBuildLocations(key, machine.getDirection(storage)).keySet()) {
        blocksToKeys.put(block, key);
        keysToBlocks.put(key, block);
    }
    return new Pair<>(machine, storage);
}
Also used : Block(org.bukkit.block.Block) Machine(com.easterlyn.machine.Machine) Pair(com.github.jikoo.planarwrappers.tuple.Pair) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

Pair (com.github.jikoo.planarwrappers.tuple.Pair)6 Nullable (org.jetbrains.annotations.Nullable)4 Machine (com.easterlyn.machine.Machine)3 Block (org.bukkit.block.Block)3 ConfigurationSection (org.bukkit.configuration.ConfigurationSection)3 HashMap (java.util.HashMap)2 Map (java.util.Map)2 ItemStack (org.bukkit.inventory.ItemStack)2 NotNull (org.jetbrains.annotations.NotNull)2 EasterlynCaptchas (com.easterlyn.EasterlynCaptchas)1 Effect (com.easterlyn.effect.Effect)1 ReportableEvent (com.easterlyn.event.ReportableEvent)1 BlockUtil (com.easterlyn.util.BlockUtil)1 ItemUtil (com.easterlyn.util.inventory.ItemUtil)1 BlockMap (com.github.jikoo.planarwrappers.collections.BlockMap)1 BlockMultimap (com.github.jikoo.planarwrappers.collections.BlockMultimap)1 Event (com.github.jikoo.planarwrappers.event.Event)1 Coords (com.github.jikoo.planarwrappers.util.Coords)1 Direction (com.github.jikoo.planarwrappers.world.Direction)1 CreeperConfig (com.nitnelave.CreeperHeal.config.CreeperConfig)1