com.sk89q.craftbook.sponge.mechanics.BounceBlocks.java Source code

Java tutorial

Introduction

Here is the source code for com.sk89q.craftbook.sponge.mechanics.BounceBlocks.java

Source

/*
 * CraftBook Copyright (C) 2010-2018 sk89q <http://www.sk89q.com>
 * CraftBook Copyright (C) 2011-2018 me4502 <http://www.me4502.com>
 * CraftBook Copyright (C) Contributors
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
 * License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program. If not,
 * see <http://www.gnu.org/licenses/>.
 */
package com.sk89q.craftbook.sponge.mechanics;

import com.flowpowered.math.vector.Vector3d;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.reflect.TypeToken;
import com.google.inject.Inject;
import com.me4502.modularframework.module.Module;
import com.me4502.modularframework.module.guice.ModuleConfiguration;
import com.sk89q.craftbook.core.util.ConfigValue;
import com.sk89q.craftbook.core.util.CraftBookException;
import com.sk89q.craftbook.core.util.PermissionNode;
import com.sk89q.craftbook.core.util.RegexUtil;
import com.sk89q.craftbook.core.util.documentation.DocumentationProvider;
import com.sk89q.craftbook.sponge.mechanics.types.SpongeSignMechanic;
import com.sk89q.craftbook.sponge.util.SpongeBlockFilter;
import com.sk89q.craftbook.sponge.util.BlockUtil;
import com.sk89q.craftbook.sponge.util.SignUtil;
import com.sk89q.craftbook.sponge.util.SpongePermissionNode;
import com.sk89q.craftbook.sponge.util.type.TypeTokens;
import ninja.leaping.configurate.ConfigurationNode;
import org.apache.commons.lang3.StringUtils;
import org.spongepowered.api.block.BlockTypes;
import org.spongepowered.api.block.tileentity.Sign;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.data.type.DyeColors;
import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.entity.MoveEntityEvent;
import org.spongepowered.api.service.permission.PermissionDescription;
import org.spongepowered.api.service.permission.Subject;
import org.spongepowered.api.util.Direction;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;

import java.util.List;
import java.util.Map;

@Module(id = "bounceblocks", name = "BounceBlocks", onEnable = "onInitialize", onDisable = "onDisable")
public class BounceBlocks extends SpongeSignMechanic implements DocumentationProvider {

    @Inject
    @ModuleConfiguration
    public ConfigurationNode config;

    private SpongePermissionNode createPermissions = new SpongePermissionNode("craftbook.bounceblocks",
            "Allows the user to create the " + getName() + " mechanic.", PermissionDescription.ROLE_USER);
    private SpongePermissionNode usePermissions = new SpongePermissionNode("craftbook.bounceblocks.use",
            "Allows the user to use the " + getName() + " mechanic.", PermissionDescription.ROLE_USER);

    private ConfigValue<List<SpongeBlockFilter>> allowedBlocks = new ConfigValue<>("allowed-blocks",
            "The list of blocks that can be normal bounce blocks.", getDefaultBlocks(),
            new TypeTokens.BlockFilterListTypeToken());
    private ConfigValue<Double> sensitivity = new ConfigValue<>("sensitivity", "Sensitivity of jump detection.",
            0.1d, TypeToken.of(Double.class));
    private ConfigValue<Map<SpongeBlockFilter, String>> autoBlocks = new ConfigValue<>("auto-blocks",
            "Bounce blocks that are predefined.",
            Maps.newHashMap(ImmutableMap.of(new SpongeBlockFilter(BlockTypes.STAINED_HARDENED_CLAY.getDefaultState()
                    .with(Keys.DYE_COLOR, DyeColors.ORANGE).get()), "2,1,2")),
            new TypeToken<Map<SpongeBlockFilter, String>>() {
            });

    @Override
    public void onInitialize() throws CraftBookException {
        super.onInitialize();

        allowedBlocks.load(config);
        sensitivity.load(config);
        autoBlocks.load(config);

        createPermissions.register();
        usePermissions.register();
    }

    @Listener
    public void onEntityMove(MoveEntityEvent event) {
        Vector3d fromPosition = event.getFromTransform().getPosition();
        Vector3d toPosition = event.getToTransform().getPosition();

        if (Math.abs(toPosition.getY() - fromPosition.getY()) > sensitivity.getValue()
                && fromPosition.getY() - fromPosition.getFloorY() < 0.25) {
            Location<World> block = event.getFromTransform().getLocation().getRelative(Direction.DOWN);

            if (BlockUtil.doesStatePassFilters(allowedBlocks.getValue(), block.getBlock())) {
                Location<World> signBlock = block.getRelative(Direction.DOWN);
                if (SignUtil.isSign(signBlock)) {
                    Sign sign = (Sign) signBlock.getTileEntity().get();
                    if (isMechanicSign(sign)) {
                        doAction(event.getTargetEntity(), SignUtil.getTextRaw(sign, 2),
                                event.getToTransform().getRotation());
                    }
                }
            } else {
                for (Map.Entry<SpongeBlockFilter, String> blockFilterStringEntry : autoBlocks.getValue()
                        .entrySet()) {
                    if (blockFilterStringEntry.getKey().getApplicableBlocks().contains(block.getBlock())) {
                        doAction(event.getTargetEntity(), blockFilterStringEntry.getValue(),
                                event.getToTransform().getRotation());
                    }
                }
            }
        }
    }

    private void doAction(Entity entity, String positionString, Vector3d rotation) {
        if (entity instanceof Player) {
            if (!usePermissions.hasPermission((Subject) entity)) {
                return;
            }
        }

        double x = 0;
        double y;
        double z = 0;
        boolean straight = positionString.startsWith("!");

        String[] bits = RegexUtil.COMMA_PATTERN.split(StringUtils.replace(positionString, "!", ""));
        if (bits.length == 0) {
            y = 0.5;
        } else if (bits.length == 1) {
            try {
                y = Double.parseDouble(bits[0]);
            } catch (NumberFormatException e) {
                y = 0.5;
            }
        } else {
            x = Double.parseDouble(bits[0]);
            y = Double.parseDouble(bits[1]);
            z = Double.parseDouble(bits[2]);
        }

        if (!straight) {
            double pitch = ((rotation.getX() + 90d) * Math.PI) / 180d;
            double yaw = ((rotation.getY() + 90d) * Math.PI) / 180d;

            x *= Math.sin(pitch) * Math.cos(yaw);
            z *= Math.sin(pitch) * Math.sin(yaw);
        }

        entity.setVelocity(new Vector3d(x, y, z));
        entity.offer(Keys.FALL_DISTANCE, -20f);
    }

    @Override
    public String getPath() {
        return "mechanics/bounce_blocks";
    }

    @Override
    public boolean isValid(Location<World> location) {
        if (location.getBlockY() >= 1) {
            Location<World> below = location.getRelative(Direction.DOWN);
            if (SignUtil.isSign(below)) {
                Sign sign = (Sign) below.getTileEntity().get();

                return isMechanicSign(sign);
            }
        }
        return false;
    }

    private static List<SpongeBlockFilter> getDefaultBlocks() {
        return Lists.newArrayList(new SpongeBlockFilter(BlockTypes.DIAMOND_BLOCK));
    }

    @Override
    public String[] getValidSigns() {
        return new String[] { "[Jump]" };
    }

    @Override
    public SpongePermissionNode getCreatePermission() {
        return createPermissions;
    }

    @Override
    public ConfigValue<?>[] getConfigurationNodes() {
        return new ConfigValue[] { allowedBlocks, sensitivity, autoBlocks };
    }

    @Override
    public PermissionNode[] getPermissionNodes() {
        return new PermissionNode[] { createPermissions, usePermissions };
    }
}