Search in sources :

Example 6 with MovecraftLocation

use of net.countercraft.movecraft.MovecraftLocation in project Movecraft by APDevTeam.

the class TranslationTask method execute.

@Override
protected void execute() throws InterruptedException, ExecutionException {
    // Check if theres anything to move
    if (oldHitBox.isEmpty())
        return;
    if (getCraft().getDisabled() && !(craft instanceof SinkingCraft)) {
        fail(I18nSupport.getInternationalisedString("Translation - Failed Craft Is Disabled"));
        return;
    }
    // call event
    final CraftPreTranslateEvent preTranslateEvent = new CraftPreTranslateEvent(craft, dx, dy, dz, world);
    Bukkit.getServer().getPluginManager().callEvent(preTranslateEvent);
    if (preTranslateEvent.isCancelled()) {
        fail(preTranslateEvent.getFailMessage(), preTranslateEvent.isPlayingFailSound());
        return;
    }
    if (dx != preTranslateEvent.getDx())
        dx = preTranslateEvent.getDx();
    if (dy != preTranslateEvent.getDy())
        dy = preTranslateEvent.getDy();
    if (dz != preTranslateEvent.getDz())
        dz = preTranslateEvent.getDz();
    world = preTranslateEvent.getWorld();
    final int minY = oldHitBox.getMinY();
    final int maxY = oldHitBox.getMaxY();
    // proccess nether portals
    if (Settings.CraftsUseNetherPortals && craft.getWorld().getEnvironment() != Environment.THE_END && world.equals(craft.getWorld())) {
        // ensure chunks are loaded for portal checking only if change in location is
        // large
        Set<MovecraftChunk> chunksToLoad = ChunkManager.getChunks(oldHitBox, world, dx, dy, dz);
        MovecraftChunk.addSurroundingChunks(chunksToLoad, 2);
        ChunkManager.checkChunks(chunksToLoad);
        if (!chunksToLoad.isEmpty())
            ChunkManager.syncLoadChunks(chunksToLoad).get();
        for (MovecraftLocation oldLocation : oldHitBox) {
            Location location = oldLocation.translate(dx, dy, dz).toBukkit(craft.getWorld());
            Block block = craft.getWorld().getBlockAt(location);
            if (block.getType() == Material.NETHER_PORTAL) {
                if (processNetherPortal(block)) {
                    sound = Sound.BLOCK_PORTAL_TRAVEL;
                    volume = 0.25f;
                    break;
                }
            }
        }
    }
    // ensure chunks are loaded only if world is different or change in location is
    // large
    Set<MovecraftChunk> chunksToLoad = ChunkManager.getChunks(oldHitBox, craft.getWorld());
    chunksToLoad.addAll(ChunkManager.getChunks(oldHitBox, world, dx, dy, dz));
    MovecraftChunk.addSurroundingChunks(chunksToLoad, 1);
    ChunkManager.checkChunks(chunksToLoad);
    if (!chunksToLoad.isEmpty())
        ChunkManager.syncLoadChunks(chunksToLoad).get();
    // Check if the craft is too high
    if (world.equals(craft.getWorld()) && (int) craft.getType().getPerWorldProperty(CraftType.PER_WORLD_MAX_HEIGHT_LIMIT, craft.getWorld()) < craft.getHitBox().getMinY())
        dy = Math.min(dy, -1);
    else if (world.equals(craft.getWorld()) && (int) craft.getType().getPerWorldProperty(CraftType.PER_WORLD_MAX_HEIGHT_ABOVE_GROUND, craft.getWorld()) > 0) {
        final MovecraftLocation middle = oldHitBox.getMidPoint();
        int testY = minY;
        while (testY > 0) {
            testY--;
            if (!craft.getWorld().getBlockAt(middle.getX(), testY, middle.getZ()).getType().isAir())
                break;
        }
        if (maxY - testY > (int) craft.getType().getPerWorldProperty(CraftType.PER_WORLD_MAX_HEIGHT_ABOVE_GROUND, world))
            dy = Math.min(dy, -1);
    }
    // Process gravity
    if (world.equals(craft.getWorld()) && craft.getType().getBoolProperty(CraftType.USE_GRAVITY) && !(craft instanceof SinkingCraft)) {
        int incline = inclineCraft(oldHitBox);
        if (incline > 0) {
            boolean tooSteep = craft.getType().getIntProperty(CraftType.GRAVITY_INCLINE_DISTANCE) > -1 && incline > craft.getType().getIntProperty(CraftType.GRAVITY_INCLINE_DISTANCE);
            if (tooSteep && craft.getType().getFloatProperty(CraftType.COLLISION_EXPLOSION) <= 0F) {
                fail(I18nSupport.getInternationalisedString("Translation - Failed Incline too steep"));
                return;
            }
            dy = tooSteep ? 0 : incline;
        } else if (!isOnGround(oldHitBox) && craft.getType().getBoolProperty(CraftType.CAN_HOVER)) {
            MovecraftLocation midPoint = oldHitBox.getMidPoint();
            int centreMinY = oldHitBox.getMinYAt(midPoint.getX(), midPoint.getZ());
            int groundY = centreMinY;
            World w = craft.getWorld();
            while (groundY - 1 >= WorldUtils.getWorldMinHeightLimit(w) && (w.getBlockAt(midPoint.getX(), groundY - 1, midPoint.getZ()).getType().isAir() || craft.getType().getMaterialSetProperty(CraftType.PASSTHROUGH_BLOCKS).contains(w.getBlockAt(midPoint.getX(), groundY - 1, midPoint.getZ()).getType()))) {
                groundY--;
            }
            if (centreMinY - groundY > craft.getType().getIntProperty(CraftType.HOVER_LIMIT))
                dy = -1;
        } else if (!isOnGround(oldHitBox))
            dy = dropDistance(oldHitBox);
    }
    // Fail the movement if the craft is too high and if the craft is not explosive
    int maxHeightLimit = (int) craft.getType().getPerWorldProperty(CraftType.PER_WORLD_MAX_HEIGHT_LIMIT, world);
    int minHeightLimit = (int) craft.getType().getPerWorldProperty(CraftType.PER_WORLD_MIN_HEIGHT_LIMIT, world);
    if (dy > 0 && maxY + dy > maxHeightLimit && craft.getType().getFloatProperty(CraftType.COLLISION_EXPLOSION) <= 0F) {
        fail(I18nSupport.getInternationalisedString("Translation - Failed Craft hit height limit"));
        return;
    } else if (dy > 0 && maxY + dy > maxHeightLimit) {
        // If explosive and too high, set dy to 0
        dy = 0;
    } else if (minY + dy < minHeightLimit && dy < 0 && !(craft instanceof SinkingCraft) && !craft.getType().getBoolProperty(CraftType.USE_GRAVITY)) {
        fail(I18nSupport.getInternationalisedString("Translation - Failed Craft hit minimum height limit"));
        return;
    } else if (minY + dy < minHeightLimit && dy < 0 && craft.getType().getBoolProperty(CraftType.USE_GRAVITY))
        // if a craft using gravity hits the minimum height limit, set dy = 0 instead of failing
        dy = 0;
    if (!(dy < 0 && dx == 0 && dz == 0) && !checkFuel()) {
        fail(I18nSupport.getInternationalisedString("Translation - Failed Craft out of fuel"));
        return;
    }
    final EnumSet<Material> harvestBlocks = craft.getType().getMaterialSetProperty(CraftType.HARVEST_BLOCKS);
    final List<MovecraftLocation> harvestedBlocks = new ArrayList<>();
    final EnumSet<Material> harvesterBladeBlocks = craft.getType().getMaterialSetProperty(CraftType.HARVESTER_BLADE_BLOCKS);
    final SetHitBox collisionBox = new SetHitBox();
    for (MovecraftLocation oldLocation : oldHitBox) {
        final MovecraftLocation newLocation = oldLocation.translate(dx, dy, dz);
        // itself
        if (world.equals(craft.getWorld()) && oldHitBox.contains(newLocation)) {
            newHitBox.add(newLocation);
            continue;
        }
        final Material testMaterial = newLocation.toBukkit(world).getBlock().getType();
        if (Tags.CHESTS.contains(testMaterial) && checkChests(testMaterial, newLocation)) {
            // prevent chests collision
            fail(String.format(I18nSupport.getInternationalisedString("Translation - Failed Craft is obstructed") + " @ %d,%d,%d,%s", newLocation.getX(), newLocation.getY(), newLocation.getZ(), newLocation.toBukkit(craft.getWorld()).getBlock().getType()));
            return;
        }
        if (!withinWorldBorder(world, newLocation)) {
            fail(I18nSupport.getInternationalisedString("Translation - Failed Craft cannot pass world border") + String.format(" @ %d,%d,%d", newLocation.getX(), newLocation.getY(), newLocation.getZ()));
            return;
        }
        boolean blockObstructed;
        if (craft instanceof SinkingCraft)
            blockObstructed = !Tags.FALL_THROUGH_BLOCKS.contains(testMaterial);
        else
            blockObstructed = !testMaterial.equals(Material.AIR) && !craft.getType().getMaterialSetProperty(CraftType.PASSTHROUGH_BLOCKS).contains(testMaterial);
        boolean ignoreBlock = oldLocation.toBukkit(craft.getWorld()).getBlock().getType().isAir() && blockObstructed;
        if (blockObstructed && !harvestBlocks.isEmpty() && harvestBlocks.contains(testMaterial)) {
            Material tmpType = oldLocation.toBukkit(craft.getWorld()).getBlock().getType();
            if (harvesterBladeBlocks.size() > 0 && harvesterBladeBlocks.contains(tmpType)) {
                blockObstructed = false;
                harvestedBlocks.add(newLocation);
            }
        }
        if (blockObstructed) {
            if (!(craft instanceof SinkingCraft) && craft.getType().getFloatProperty(CraftType.COLLISION_EXPLOSION) <= 0F) {
                fail(String.format(I18nSupport.getInternationalisedString("Translation - Failed Craft is obstructed") + " @ %d,%d,%d,%s", newLocation.getX(), newLocation.getY(), newLocation.getZ(), testMaterial));
                return;
            }
            collisionBox.add(newLocation);
        } else if (!ignoreBlock)
            newHitBox.add(newLocation);
    }
    if (!oldFluidList.isEmpty()) {
        for (MovecraftLocation fluidLoc : oldFluidList) {
            newFluidList.add(fluidLoc.translate(dx, dy, dz));
        }
    }
    if (craft.getType().getMaterialSetProperty(CraftType.FORBIDDEN_HOVER_OVER_BLOCKS).size() > 0) {
        MovecraftLocation test = new MovecraftLocation(newHitBox.getMidPoint().getX(), newHitBox.getMinY(), newHitBox.getMidPoint().getZ());
        test = test.translate(0, -1, 0);
        while (test.toBukkit(world).getBlock().getType().isAir()) {
            test = test.translate(0, -1, 0);
        }
        Material testType = test.toBukkit(world).getBlock().getType();
        if (craft.getType().getMaterialSetProperty(CraftType.FORBIDDEN_HOVER_OVER_BLOCKS).contains(testType)) {
            fail(String.format(I18nSupport.getInternationalisedString("Translation - Failed Craft over block"), testType.name().toLowerCase().replace("_", " ")));
        }
    }
    // call event
    CraftTranslateEvent translateEvent = new CraftTranslateEvent(craft, oldHitBox, newHitBox, world);
    Bukkit.getServer().getPluginManager().callEvent(translateEvent);
    if (translateEvent.isCancelled()) {
        this.fail(translateEvent.getFailMessage(), translateEvent.isPlayingFailSound());
        return;
    }
    // do not switch world if sinking
    if (craft instanceof SinkingCraft) {
        List<MovecraftLocation> air = new ArrayList<>();
        for (MovecraftLocation location : oldHitBox) {
            if (location.toBukkit(craft.getWorld()).getBlock().getType().isAir()) {
                air.add(location.translate(dx, dy, dz));
            }
        }
        newHitBox.removeAll(air);
        for (MovecraftLocation location : collisionBox) {
            if (craft.getType().getFloatProperty(CraftType.EXPLODE_ON_CRASH) > 0F) {
                if (System.currentTimeMillis() - craft.getOrigPilotTime() <= 1000) {
                    continue;
                }
                Location loc = location.toBukkit(craft.getWorld());
                if (!loc.getBlock().getType().isAir() && ThreadLocalRandom.current().nextDouble(1) < .05) {
                    updates.add(new ExplosionUpdateCommand(loc, craft.getType().getFloatProperty(CraftType.EXPLODE_ON_CRASH)));
                    collisionExplosion = true;
                }
            }
            SetHitBox toRemove = new SetHitBox();
            MovecraftLocation next = location.translate(-dx, -dy, -dz);
            while (oldHitBox.contains(next)) {
                toRemove.add(next);
                next = next.translate(0, 1, 0);
            }
            craft.getCollapsedHitBox().addAll(toRemove);
            newHitBox.removeAll(toRemove);
        }
    } else if ((craft.getType().getFloatProperty(CraftType.COLLISION_EXPLOSION) > 0F) && System.currentTimeMillis() - craft.getOrigPilotTime() > Settings.CollisionPrimer) {
        for (MovecraftLocation location : collisionBox) {
            float explosionForce = craft.getType().getFloatProperty(CraftType.COLLISION_EXPLOSION);
            if (craft.getType().getBoolProperty(CraftType.FOCUSED_EXPLOSION)) {
                explosionForce *= Math.min(oldHitBox.size(), craft.getType().getIntProperty(CraftType.MAX_SIZE));
            }
            // TODO: Account for underwater explosions
            /*if (location.getY() < waterLine) { // underwater explosions require more force to do anything
                    explosionForce += 25;//TODO: find the correct amount
                }*/
            Location oldLocation = location.translate(-dx, -dy, -dz).toBukkit(craft.getWorld());
            Location newLocation = location.toBukkit(world);
            if (!oldLocation.getBlock().getType().isAir()) {
                CraftCollisionExplosionEvent e = new CraftCollisionExplosionEvent(craft, newLocation, craft.getWorld());
                Bukkit.getServer().getPluginManager().callEvent(e);
                if (!e.isCancelled()) {
                    updates.add(new ExplosionUpdateCommand(newLocation, explosionForce));
                    collisionExplosion = true;
                }
            }
            if (craft.getType().getBoolProperty(CraftType.FOCUSED_EXPLOSION)) {
                // don't handle any further collisions if it is set to focusedexplosion
                break;
            }
        }
    }
    if (!collisionBox.isEmpty() && craft.getType().getBoolProperty(CraftType.CRUISE_ON_PILOT)) {
        CraftManager.getInstance().release(craft, CraftReleaseEvent.Reason.EMPTY, false);
        for (MovecraftLocation location : oldHitBox) {
            BlockData phaseBlock = craft.getPhaseBlocks().getOrDefault(location.toBukkit(craft.getWorld()), Material.AIR.createBlockData());
            updates.add(new BlockCreateCommand(craft.getWorld(), location, phaseBlock));
        }
        newHitBox = new SetHitBox();
    }
    if (!collisionBox.isEmpty()) {
        Bukkit.getServer().getPluginManager().callEvent(new CraftCollisionEvent(craft, collisionBox, world));
    }
    updates.add(new CraftTranslateCommand(craft, new MovecraftLocation(dx, dy, dz), world));
    // prevents torpedo and rocket pilots
    if (!(craft instanceof SinkingCraft && craft.getType().getBoolProperty(CraftType.ONLY_MOVE_PLAYERS)) && craft.getType().getBoolProperty(CraftType.MOVE_ENTITIES)) {
        Location midpoint = new Location(craft.getWorld(), (oldHitBox.getMaxX() + oldHitBox.getMinX()) / 2.0, (oldHitBox.getMaxY() + oldHitBox.getMinY()) / 2.0, (oldHitBox.getMaxZ() + oldHitBox.getMinZ()) / 2.0);
        for (Entity entity : craft.getWorld().getNearbyEntities(midpoint, oldHitBox.getXLength() / 2.0 + 1, oldHitBox.getYLength() / 2.0 + 2, oldHitBox.getZLength() / 2.0 + 1)) {
            if (entity.getType() == EntityType.PLAYER) {
                if (craft instanceof SinkingCraft)
                    continue;
                EntityUpdateCommand eUp = new EntityUpdateCommand(entity, dx, dy, dz, 0, 0, world, sound, volume);
                updates.add(eUp);
            } else if (!craft.getType().getBoolProperty(CraftType.ONLY_MOVE_PLAYERS) || entity.getType() == EntityType.PRIMED_TNT) {
                EntityUpdateCommand eUp = new EntityUpdateCommand(entity, dx, dy, dz, 0, 0, world);
                updates.add(eUp);
            }
        }
    } else {
        // add releaseTask without playermove to manager
        if (!craft.getType().getBoolProperty(CraftType.CRUISE_ON_PILOT) && !(craft instanceof SinkingCraft))
            // not necessary to release cruiseonpilot crafts, because they will already be released
            CraftManager.getInstance().addReleaseTask(craft);
    }
    captureYield(harvestedBlocks);
}
Also used : CraftTranslateCommand(net.countercraft.movecraft.mapUpdater.update.CraftTranslateCommand) Entity(org.bukkit.entity.Entity) ArrayList(java.util.ArrayList) SetHitBox(net.countercraft.movecraft.util.hitboxes.SetHitBox) Material(org.bukkit.Material) CraftTranslateEvent(net.countercraft.movecraft.events.CraftTranslateEvent) CraftCollisionEvent(net.countercraft.movecraft.events.CraftCollisionEvent) World(org.bukkit.World) SinkingCraft(net.countercraft.movecraft.craft.SinkingCraft) CraftPreTranslateEvent(net.countercraft.movecraft.events.CraftPreTranslateEvent) ExplosionUpdateCommand(net.countercraft.movecraft.mapUpdater.update.ExplosionUpdateCommand) CraftCollisionExplosionEvent(net.countercraft.movecraft.events.CraftCollisionExplosionEvent) Block(org.bukkit.block.Block) MovecraftLocation(net.countercraft.movecraft.MovecraftLocation) BlockData(org.bukkit.block.data.BlockData) BlockCreateCommand(net.countercraft.movecraft.mapUpdater.update.BlockCreateCommand) EntityUpdateCommand(net.countercraft.movecraft.mapUpdater.update.EntityUpdateCommand) MovecraftChunk(net.countercraft.movecraft.MovecraftChunk) Location(org.bukkit.Location) MovecraftLocation(net.countercraft.movecraft.MovecraftLocation)

Example 7 with MovecraftLocation

use of net.countercraft.movecraft.MovecraftLocation in project Movecraft by APDevTeam.

the class ContactsCommand method onCommand.

@Override
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) {
    if (!command.getName().equalsIgnoreCase("contacts")) {
        return false;
    }
    if (!(commandSender instanceof Player)) {
        commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Contacts - Must Be Player"));
        return true;
    }
    Player player = (Player) commandSender;
    if (CraftManager.getInstance().getCraftByPlayer(player) == null) {
        player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("You must be piloting a craft"));
        return true;
    }
    int page;
    try {
        if (args.length == 0)
            page = 1;
        else
            page = Integer.parseInt(args[0]);
    } catch (NumberFormatException e) {
        commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Paginator - Invalid Page") + " \"" + args[0] + "\"");
        return true;
    }
    TopicPaginator pageinator = new TopicPaginator(I18nSupport.getInternationalisedString("Contacts"));
    Craft ccraft = CraftManager.getInstance().getCraftByPlayer(player);
    HitBox hitBox = ccraft.getHitBox();
    MovecraftLocation center = hitBox.getMidPoint();
    for (Craft tcraft : ccraft.getContacts()) {
        HitBox tHitBox = tcraft.getHitBox();
        if (tHitBox.isEmpty())
            continue;
        MovecraftLocation tCenter = tHitBox.getMidPoint();
        int distsquared = center.distanceSquared(tCenter);
        String notification = I18nSupport.getInternationalisedString("Contact");
        notification += ": ";
        notification += tcraft instanceof SinkingCraft ? ChatColor.RED : tcraft.getDisabled() ? ChatColor.BLUE : "";
        notification += tcraft.getName().length() >= 1 ? tcraft.getName() + " (" : "";
        notification += tcraft.getType().getStringProperty(CraftType.NAME);
        notification += tcraft.getName().length() >= 1 ? ") " : " ";
        notification += ChatColor.RESET;
        notification += I18nSupport.getInternationalisedString("Contact - Commanded By") + ", ";
        notification += tcraft instanceof PilotedCraft ? ((PilotedCraft) tcraft).getPilot().getDisplayName() : "null";
        notification += " ";
        notification += I18nSupport.getInternationalisedString("Contact - Size") + " ";
        notification += tcraft.getOrigBlockCount();
        notification += ", " + I18nSupport.getInternationalisedString("Contact - Range") + " ";
        notification += (int) Math.sqrt(distsquared);
        notification += " " + I18nSupport.getInternationalisedString("Contact - To The");
        int diffx = center.getX() - tCenter.getX();
        int diffz = center.getZ() - tCenter.getZ();
        if (Math.abs(diffx) > Math.abs(diffz))
            if (diffx < 0)
                notification += " " + I18nSupport.getInternationalisedString("Contact/Subcraft Rotate - East") + ".";
            else
                notification += " " + I18nSupport.getInternationalisedString("Contact/Subcraft Rotate - West") + ".";
        else if (diffz < 0)
            notification += " " + I18nSupport.getInternationalisedString("Contact/Subcraft Rotate - South") + ".";
        else
            notification += " " + I18nSupport.getInternationalisedString("Contact/Subcraft Rotate - North") + ".";
        pageinator.addLine(notification);
    }
    if (pageinator.isEmpty()) {
        player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Contacts - None Found"));
        return true;
    }
    if (!pageinator.isInBounds(page)) {
        commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Paginator - Invalid page") + "\"" + page + "\"");
        return true;
    }
    for (String line : pageinator.getPage(page)) commandSender.sendMessage(line);
    return true;
}
Also used : SinkingCraft(net.countercraft.movecraft.craft.SinkingCraft) Player(org.bukkit.entity.Player) HitBox(net.countercraft.movecraft.util.hitboxes.HitBox) TopicPaginator(net.countercraft.movecraft.util.TopicPaginator) SinkingCraft(net.countercraft.movecraft.craft.SinkingCraft) Craft(net.countercraft.movecraft.craft.Craft) PilotedCraft(net.countercraft.movecraft.craft.PilotedCraft) PilotedCraft(net.countercraft.movecraft.craft.PilotedCraft) MovecraftLocation(net.countercraft.movecraft.MovecraftLocation)

Example 8 with MovecraftLocation

use of net.countercraft.movecraft.MovecraftLocation in project Movecraft by APDevTeam.

the class PilotCommand method onCommand.

@Override
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) {
    if (!command.getName().equalsIgnoreCase("pilot"))
        return false;
    if (!(commandSender instanceof Player)) {
        commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Pilot - Must Be Player"));
        return true;
    }
    Player player = (Player) commandSender;
    if (!player.hasPermission("movecraft.commands") || !player.hasPermission("movecraft.commands.pilot")) {
        player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Insufficient Permissions"));
        return true;
    }
    if (args.length < 1) {
        player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Pilot - No Craft Type"));
        return true;
    }
    if (!player.hasPermission("movecraft." + args[0] + ".pilot")) {
        player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Insufficient Permissions"));
        return true;
    }
    CraftType craftType = CraftManager.getInstance().getCraftTypeFromString(args[0]);
    if (craftType == null) {
        player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Pilot - Invalid Craft Type"));
        return true;
    }
    final World world = player.getWorld();
    MovecraftLocation startPoint = MathUtils.bukkit2MovecraftLoc(player.getLocation());
    CraftManager.getInstance().detect(startPoint, craftType, (type, w, p, parents) -> {
        // Note: This only passes in a non-null player.
        assert p != null;
        if (parents.size() > 0)
            return new Pair<>(Result.failWithMessage(I18nSupport.getInternationalisedString("Detection - Failed - Already commanding a craft")), null);
        return new Pair<>(Result.succeed(), new PlayerCraftImpl(type, w, p));
    }, world, player, Movecraft.getAdventure().player(player), craft -> () -> {
        // Release old craft if it exists
        Craft oldCraft = CraftManager.getInstance().getCraftByPlayer(player);
        if (oldCraft != null)
            CraftManager.getInstance().release(oldCraft, CraftReleaseEvent.Reason.PLAYER, false);
    });
    return true;
}
Also used : Player(org.bukkit.entity.Player) PlayerCraftImpl(net.countercraft.movecraft.craft.PlayerCraftImpl) CruiseOnPilotCraft(net.countercraft.movecraft.craft.CruiseOnPilotCraft) CruiseOnPilotSubCraft(net.countercraft.movecraft.craft.CruiseOnPilotSubCraft) Craft(net.countercraft.movecraft.craft.Craft) World(org.bukkit.World) MovecraftLocation(net.countercraft.movecraft.MovecraftLocation) CraftType(net.countercraft.movecraft.craft.type.CraftType) Pair(net.countercraft.movecraft.util.Pair)

Example 9 with MovecraftLocation

use of net.countercraft.movecraft.MovecraftLocation in project Movecraft by APDevTeam.

the class PlayerListener method checkCraftBorders.

private Set<Location> checkCraftBorders(Craft craft) {
    Set<Location> mergePoints = new HashSet<>();
    final EnumSet<Material> ALLOWED_BLOCKS = craft.getType().getMaterialSetProperty(CraftType.ALLOWED_BLOCKS);
    final EnumSet<Material> FORBIDDEN_BLOCKS = craft.getType().getMaterialSetProperty(CraftType.FORBIDDEN_BLOCKS);
    final MovecraftLocation[] SHIFTS = { // x
    new MovecraftLocation(-1, 0, 0), new MovecraftLocation(-1, -1, 0), new MovecraftLocation(-1, 1, 0), new MovecraftLocation(1, -1, 0), new MovecraftLocation(1, 1, 0), new MovecraftLocation(1, 0, 0), // z
    new MovecraftLocation(0, 1, 1), new MovecraftLocation(0, 0, 1), new MovecraftLocation(0, -1, 1), new MovecraftLocation(0, 1, -1), new MovecraftLocation(0, 0, -1), new MovecraftLocation(0, -1, -1), // y
    new MovecraftLocation(0, 1, 0), new MovecraftLocation(0, -1, 0) };
    // Check each location in the hitbox
    for (MovecraftLocation ml : craft.getHitBox()) {
        // Check the surroundings of each location
        for (MovecraftLocation shift : SHIFTS) {
            MovecraftLocation test = ml.add(shift);
            // Ignore locations contained in the craft's hitbox
            if (craft.getHitBox().contains(test)) {
                continue;
            }
            Block testBlock = test.toBukkit(craft.getWorld()).getBlock();
            Material testMaterial = testBlock.getType();
            // Break the loop if an allowed block is found adjacent to the craft's hitbox
            if (ALLOWED_BLOCKS.contains(testMaterial)) {
                mergePoints.add(testBlock.getLocation());
            } else // Do the same if a forbidden block is found
            if (FORBIDDEN_BLOCKS.contains(testMaterial)) {
                mergePoints.add(testBlock.getLocation());
            }
        }
    }
    // Return the string representation of the merging point and alert the pilot
    return mergePoints;
}
Also used : Block(org.bukkit.block.Block) Material(org.bukkit.Material) MovecraftLocation(net.countercraft.movecraft.MovecraftLocation) Location(org.bukkit.Location) MovecraftLocation(net.countercraft.movecraft.MovecraftLocation) HashSet(java.util.HashSet)

Example 10 with MovecraftLocation

use of net.countercraft.movecraft.MovecraftLocation in project Movecraft by APDevTeam.

the class CraftRotateCommand method doUpdate.

@Override
public void doUpdate() {
    final Logger logger = Movecraft.getInstance().getLogger();
    if (craft.getHitBox().isEmpty()) {
        logger.warning("Attempted to move craft with empty HashHitBox!");
        CraftManager.getInstance().release(craft, CraftReleaseEvent.Reason.EMPTY, false);
        return;
    }
    long time = System.nanoTime();
    final Set<Material> passthroughBlocks = new HashSet<>(craft.getType().getMaterialSetProperty(CraftType.PASSTHROUGH_BLOCKS));
    if (craft instanceof SinkingCraft) {
        passthroughBlocks.addAll(Tags.FLUID);
        passthroughBlocks.addAll(Tag.LEAVES.getValues());
        passthroughBlocks.addAll(Tags.SINKING_PASSTHROUGH);
    }
    if (!passthroughBlocks.isEmpty()) {
        SetHitBox originalLocations = new SetHitBox();
        final MovecraftRotation counterRotation = rotation == MovecraftRotation.CLOCKWISE ? MovecraftRotation.ANTICLOCKWISE : MovecraftRotation.CLOCKWISE;
        for (MovecraftLocation movecraftLocation : craft.getHitBox()) {
            originalLocations.add(MathUtils.rotateVec(counterRotation, movecraftLocation.subtract(originLocation)).add(originLocation));
        }
        final HitBox to = craft.getHitBox().difference(originalLocations);
        for (MovecraftLocation location : to) {
            var data = location.toBukkit(craft.getWorld()).getBlock().getBlockData();
            if (passthroughBlocks.contains(data.getMaterial())) {
                craft.getPhaseBlocks().put(location.toBukkit(craft.getWorld()), data);
            }
        }
        // The subtraction of the set of coordinates in the HitBox cube and the HitBox itself
        final HitBox invertedHitBox = new SetHitBox(craft.getHitBox().boundingHitBox()).difference(craft.getHitBox());
        // A set of locations that are confirmed to be "exterior" locations
        final SetHitBox exterior = new SetHitBox();
        final SetHitBox interior = new SetHitBox();
        // place phased blocks
        final Set<Location> overlap = new HashSet<>(craft.getPhaseBlocks().keySet());
        overlap.retainAll(craft.getHitBox().asSet().stream().map(l -> l.toBukkit(craft.getWorld())).collect(Collectors.toSet()));
        final int minX = craft.getHitBox().getMinX();
        final int maxX = craft.getHitBox().getMaxX();
        final int minY = craft.getHitBox().getMinY();
        final int maxY = overlap.isEmpty() ? craft.getHitBox().getMaxY() : Collections.max(overlap, Comparator.comparingInt(Location::getBlockY)).getBlockY();
        final int minZ = craft.getHitBox().getMinZ();
        final int maxZ = craft.getHitBox().getMaxZ();
        final HitBox[] surfaces = { new SolidHitBox(new MovecraftLocation(minX, minY, minZ), new MovecraftLocation(minX, maxY, maxZ)), new SolidHitBox(new MovecraftLocation(minX, minY, minZ), new MovecraftLocation(maxX, maxY, minZ)), new SolidHitBox(new MovecraftLocation(maxX, minY, maxZ), new MovecraftLocation(minX, maxY, maxZ)), new SolidHitBox(new MovecraftLocation(maxX, minY, maxZ), new MovecraftLocation(maxX, maxY, minZ)), new SolidHitBox(new MovecraftLocation(minX, minY, minZ), new MovecraftLocation(maxX, minY, maxZ)) };
        // Valid exterior starts as the 6 surface planes of the HitBox with the locations that lie in the HitBox removed
        final SetHitBox validExterior = new SetHitBox();
        for (HitBox hitBox : surfaces) {
            validExterior.addAll(hitBox.difference(craft.getHitBox()));
        }
        // Check to see which locations in the from set are actually outside of the craft
        for (MovecraftLocation location : validExterior) {
            if (craft.getHitBox().contains(location) || exterior.contains(location)) {
                continue;
            }
            // use a modified BFS for multiple origin elements
            SetHitBox visited = new SetHitBox();
            Queue<MovecraftLocation> queue = new LinkedList<>();
            queue.add(location);
            while (!queue.isEmpty()) {
                MovecraftLocation node = queue.poll();
                // If the node is already a valid member of the exterior of the HitBox, continued search is unitary.
                for (MovecraftLocation neighbor : CollectionUtils.neighbors(invertedHitBox, node)) {
                    if (visited.contains(neighbor)) {
                        continue;
                    }
                    visited.add(neighbor);
                    queue.add(neighbor);
                }
            }
            exterior.addAll(visited);
        }
        interior.addAll(invertedHitBox.difference(exterior));
        final WorldHandler handler = Movecraft.getInstance().getWorldHandler();
        for (MovecraftLocation location : invertedHitBox.difference(exterior)) {
            var data = location.toBukkit(craft.getWorld()).getBlock().getBlockData();
            if (!passthroughBlocks.contains(data.getMaterial())) {
                continue;
            }
            craft.getPhaseBlocks().put(location.toBukkit(craft.getWorld()), data);
        }
        // translate the craft
        handler.rotateCraft(craft, originLocation, rotation);
        // trigger sign events
        sendSignEvents();
        // place confirmed blocks if they have been un-phased
        for (MovecraftLocation location : exterior) {
            Location bukkit = location.toBukkit(craft.getWorld());
            if (!craft.getPhaseBlocks().containsKey(bukkit)) {
                continue;
            }
            var phaseBlock = craft.getPhaseBlocks().remove(bukkit);
            handler.setBlockFast(bukkit, phaseBlock);
            craft.getPhaseBlocks().remove(bukkit);
        }
        for (MovecraftLocation location : originalLocations.boundingHitBox()) {
            Location bukkit = location.toBukkit(craft.getWorld());
            if (!craft.getHitBox().inBounds(location) && craft.getPhaseBlocks().containsKey(bukkit)) {
                var phaseBlock = craft.getPhaseBlocks().remove(bukkit);
                handler.setBlockFast(bukkit, phaseBlock);
            }
        }
        for (MovecraftLocation location : interior) {
            Location bukkit = location.toBukkit(craft.getWorld());
            var data = bukkit.getBlock().getBlockData();
            if (passthroughBlocks.contains(data.getMaterial())) {
                craft.getPhaseBlocks().put(bukkit, data);
                handler.setBlockFast(bukkit, Material.AIR.createBlockData());
            }
        }
    } else {
        // translate the craft
        Movecraft.getInstance().getWorldHandler().rotateCraft(craft, originLocation, rotation);
        // trigger sign events
        sendSignEvents();
    }
    if (!craft.isNotProcessing())
        craft.setProcessing(false);
    time = System.nanoTime() - time;
    if (Settings.Debug)
        logger.info("Total time: " + (time / 1e6) + " milliseconds. Moving with cooldown of " + craft.getTickCooldown() + ". Speed of: " + String.format("%.2f", craft.getSpeed()));
}
Also used : SolidHitBox(net.countercraft.movecraft.util.hitboxes.SolidHitBox) HitBox(net.countercraft.movecraft.util.hitboxes.HitBox) SetHitBox(net.countercraft.movecraft.util.hitboxes.SetHitBox) SolidHitBox(net.countercraft.movecraft.util.hitboxes.SolidHitBox) SetHitBox(net.countercraft.movecraft.util.hitboxes.SetHitBox) Material(org.bukkit.Material) Logger(java.util.logging.Logger) WorldHandler(net.countercraft.movecraft.WorldHandler) LinkedList(java.util.LinkedList) MovecraftRotation(net.countercraft.movecraft.MovecraftRotation) SinkingCraft(net.countercraft.movecraft.craft.SinkingCraft) MovecraftLocation(net.countercraft.movecraft.MovecraftLocation) HashSet(java.util.HashSet) Location(org.bukkit.Location) MovecraftLocation(net.countercraft.movecraft.MovecraftLocation)

Aggregations

MovecraftLocation (net.countercraft.movecraft.MovecraftLocation)60 Craft (net.countercraft.movecraft.craft.Craft)18 EventHandler (org.bukkit.event.EventHandler)18 Material (org.bukkit.Material)17 World (org.bukkit.World)15 Sign (org.bukkit.block.Sign)14 BlockState (org.bukkit.block.BlockState)13 Block (org.bukkit.block.Block)12 ArrayList (java.util.ArrayList)11 Location (org.bukkit.Location)11 Map (java.util.Map)10 HashMap (java.util.HashMap)9 SetHitBox (net.countercraft.movecraft.util.hitboxes.SetHitBox)9 HashSet (java.util.HashSet)8 SinkingCraft (net.countercraft.movecraft.craft.SinkingCraft)8 NotNull (org.jetbrains.annotations.NotNull)8 MovecraftRotation (net.countercraft.movecraft.MovecraftRotation)6 HitBox (net.countercraft.movecraft.util.hitboxes.HitBox)6 SolidHitBox (net.countercraft.movecraft.util.hitboxes.SolidHitBox)6 LinkedList (java.util.LinkedList)5