Search in sources :

Example 16 with GlowEntity

use of net.glowstone.entity.GlowEntity in project Glowstone by GlowstoneMC.

the class AnvilChunkIoService method write.

@Override
public void write(GlowChunk chunk) throws IOException {
    int x = chunk.getX();
    int z = chunk.getZ();
    RegionFile region = cache.getRegionFile(x, z);
    int regionX = x & REGION_SIZE - 1;
    int regionZ = z & REGION_SIZE - 1;
    CompoundTag levelTags = new CompoundTag();
    // core properties
    // NON-NLS
    levelTags.putInt("xPos", chunk.getX());
    // NON-NLS
    levelTags.putInt("zPos", chunk.getZ());
    // NON-NLS
    levelTags.putLong("LastUpdate", 0);
    // NON-NLS
    levelTags.putLong("InhabitedTime", chunk.getInhabitedTime());
    // NON-NLS
    levelTags.putBool("TerrainPopulated", chunk.isPopulated());
    // chunk sections
    List<CompoundTag> sectionTags = new ArrayList<>();
    GlowChunkSnapshot snapshot = chunk.getChunkSnapshot(true, true, false);
    ChunkSection[] sections = snapshot.getRawSections();
    for (byte i = 0; i < sections.length; ++i) {
        ChunkSection sec = sections[i];
        if (sec == null) {
            continue;
        }
        CompoundTag sectionTag = new CompoundTag();
        // NON-NLS
        sectionTag.putByte("Y", i);
        sec.recount();
        sec.writeToNbt(sectionTag);
        sectionTags.add(sectionTag);
    }
    // NON-NLS
    levelTags.putCompoundList("Sections", sectionTags);
    // height map and biomes
    // NON-NLS
    levelTags.putIntArray("HeightMap", snapshot.getRawHeightmap());
    // NON-NLS
    levelTags.putByteArray("Biomes", snapshot.getRawBiomes());
    // Save Slime Chunk
    // NON-NLS
    levelTags.putByte("isSlimeChunk", snapshot.isSlimeChunk() ? 1 : 0);
    // entities
    List<CompoundTag> entities = new ArrayList<>();
    for (GlowEntity entity : chunk.getRawEntities()) {
        if (!entity.shouldSave()) {
            continue;
        }
        // passengers will be saved as part of the vehicle
        if (entity.isInsideVehicle()) {
            continue;
        }
        try {
            CompoundTag tag = new CompoundTag();
            EntityStorage.save(entity, tag);
            entities.add(tag);
        } catch (Exception e) {
            ConsoleMessages.Warn.Entity.SAVE_FAILED.log(e, entity, chunk);
        }
    }
    levelTags.putCompoundList("Entities", entities);
    // block entities
    List<CompoundTag> blockEntities = new ArrayList<>();
    for (BlockEntity entity : chunk.getRawBlockEntities()) {
        try {
            CompoundTag tag = new CompoundTag();
            entity.saveNbt(tag);
            blockEntities.add(tag);
        } catch (Exception ex) {
            ConsoleMessages.Error.BlockEntity.SAVE_FAILED.log(ex, entity.getBlock());
        }
    }
    levelTags.putCompoundList("TileEntities", blockEntities);
    List<CompoundTag> tileTicks = new ArrayList<>();
    for (Location location : chunk.getWorld().getTickMap()) {
        Chunk locationChunk = location.getChunk();
        if (locationChunk.getX() == chunk.getX() && locationChunk.getZ() == chunk.getZ()) {
            int tileX = location.getBlockX();
            int tileY = location.getBlockY();
            int tileZ = location.getBlockZ();
            String type = ItemIds.getName(location.getBlock().getType());
            CompoundTag tag = new CompoundTag();
            tag.putInt("x", tileX);
            tag.putInt("y", tileY);
            tag.putInt("z", tileZ);
            tag.putString("i", type);
            tileTicks.add(tag);
        }
    }
    levelTags.putCompoundList("TileTicks", tileTicks);
    CompoundTag levelOut = new CompoundTag();
    levelOut.putCompound("Level", levelTags);
    try (NbtOutputStream nbt = new NbtOutputStream(region.getChunkDataOutputStream(regionX, regionZ), false)) {
        nbt.writeTag(levelOut);
    }
}
Also used : NbtOutputStream(net.glowstone.util.nbt.NbtOutputStream) ArrayList(java.util.ArrayList) GlowChunk(net.glowstone.chunk.GlowChunk) Chunk(org.bukkit.Chunk) UnknownEntityTypeException(net.glowstone.io.entity.UnknownEntityTypeException) IOException(java.io.IOException) GlowEntity(net.glowstone.entity.GlowEntity) ChunkSection(net.glowstone.chunk.ChunkSection) CompoundTag(net.glowstone.util.nbt.CompoundTag) GlowChunkSnapshot(net.glowstone.chunk.GlowChunkSnapshot) BlockEntity(net.glowstone.block.entity.BlockEntity) Location(org.bukkit.Location)

Example 17 with GlowEntity

use of net.glowstone.entity.GlowEntity in project Glowstone by GlowstoneMC.

the class InteractEntityHandler method handle.

@Override
public void handle(GlowSession session, InteractEntityMessage message) {
    GlowPlayer player = session.getPlayer();
    EventFactory eventFactory = EventFactory.getInstance();
    // You can't do anything when you're dead
    if (player.isDead()) {
        GlowServer.logger.info("Player " + player.getName() + " tried to interact with an entity while dead");
        return;
    }
    GlowEntity possibleTarget = player.getWorld().getEntityManager().getEntity(message.getId());
    GlowLivingEntity target = possibleTarget instanceof GlowLivingEntity ? (GlowLivingEntity) possibleTarget : null;
    EquipmentSlot hand = message.getHandSlot();
    if (message.getAction() == Action.ATTACK.ordinal()) {
        if (target == null) {
            if (possibleTarget != null) {
                possibleTarget.entityInteract(player, message);
            } else {
                GlowServer.logger.info("Player " + player.getName() + " tried to attack an entity that does not exist");
            }
        } else if (!target.isDead() && target.canTakeDamage(DamageCause.ENTITY_ATTACK)) {
            // Calculate damage amount
            ItemStack itemInHand = InventoryUtil.itemOrEmpty(player.getInventory().getItem(hand));
            Material type = itemInHand.getType();
            boolean critical = player.getFallDistance() > 0.0F && !player.isOnGround() && !player.isInWater() && !player.isInsideVehicle() && !player.isSprinting();
            float damage = AttackDamage.getMeleeDamage(type, critical);
            if (critical) {
                // Critical-hit effect
                target.playAnimation(EntityAnimation.CRITICAL_HIT);
            }
            // Set entity on fire if the item has Fire Aspect
            if (itemInHand.containsEnchantment(Enchantment.FIRE_ASPECT)) {
                target.setFireTicks(target.getFireTicks() + itemInHand.getEnchantmentLevel(Enchantment.FIRE_ASPECT) * 80);
            }
            boolean showMagicCrit = false;
            // Apply other enchantments that amplify damage
            if (itemInHand.containsEnchantment(Enchantment.DAMAGE_ALL)) {
                // Sharpness
                int level = itemInHand.getEnchantmentLevel(Enchantment.DAMAGE_ALL);
                if (level > 0) {
                    damage += 1.0F + 0.5F * (level - 1);
                }
                if (!showMagicCrit) {
                    showMagicCrit = ToolType.SWORD.matches(type) || ToolType.AXE.matches(type);
                }
            }
            if (itemInHand.containsEnchantment(Enchantment.DAMAGE_ARTHROPODS)) {
                // Endermites)
                if (target.isArthropod()) {
                    int level = itemInHand.getEnchantmentLevel(Enchantment.DAMAGE_ARTHROPODS);
                    if (level > 0) {
                        damage += level * 2.5F;
                    // TODO: add Slowness potion effect (after damaging and checking for
                    // event-cancellation)
                    }
                }
                if (!showMagicCrit) {
                    showMagicCrit = ToolType.SWORD.matches(type) || ToolType.AXE.matches(type);
                }
            }
            if (itemInHand.containsEnchantment(Enchantment.DAMAGE_UNDEAD)) {
                // Smite (applies to "undead" mobs)
                if (target.isUndead()) {
                    int level = itemInHand.getEnchantmentLevel(Enchantment.DAMAGE_UNDEAD);
                    damage += level * 2.5F;
                }
                if (!showMagicCrit) {
                    showMagicCrit = ToolType.SWORD.matches(type) || ToolType.AXE.matches(type);
                }
            }
            if (showMagicCrit) {
                target.playAnimation(EntityAnimation.MAGIC_CRITICAL_HIT);
            }
            // Apply damage. Calls the EntityDamageByEntityEvent
            target.damage(damage, player, DamageCause.ENTITY_ATTACK);
            player.incrementStatistic(Statistic.DAMAGE_DEALT, Math.round(damage));
            player.addExhaustion(0.1f);
            if (target.isDead()) {
                player.incrementStatistic(target.getType() == EntityType.PLAYER ? Statistic.PLAYER_KILLS : Statistic.MOB_KILLS);
            }
            // Apply durability loss (if applicable)
            short durabilityLoss = AttackDamage.getMeleeDurabilityLoss(type);
            if (durabilityLoss > 0 && !InventoryUtil.isEmpty(itemInHand) && player.getGameMode() != GameMode.CREATIVE) {
                // Yes, this actually subtracts
                itemInHand.setDurability((short) (itemInHand.getDurability() + durabilityLoss));
            }
        }
    } else if (message.getAction() == Action.INTERACT_AT.ordinal()) {
        // used for adjusting specific portions of armor stands
        PlayerInteractAtEntityEvent event = new PlayerInteractAtEntityEvent(player, possibleTarget, new Vector(message.getTargetX(), message.getTargetY(), message.getTargetZ()), hand);
        eventFactory.callEvent(event);
        if (!event.isCancelled()) {
            possibleTarget.entityInteract(player, message);
        }
    } else if (message.getAction() == Action.INTERACT.ordinal()) {
        // Todo: Handle hand variable
        PlayerInteractEntityEvent event = new PlayerInteractEntityEvent(player, possibleTarget, hand);
        eventFactory.callEvent(event);
        if (!event.isCancelled()) {
            possibleTarget.entityInteract(player, message);
        }
    } else {
        GlowServer.logger.info("Player " + player.getName() + " sent unknown interact action: " + message.getAction());
    }
}
Also used : PlayerInteractAtEntityEvent(org.bukkit.event.player.PlayerInteractAtEntityEvent) GlowPlayer(net.glowstone.entity.GlowPlayer) GlowEntity(net.glowstone.entity.GlowEntity) EquipmentSlot(org.bukkit.inventory.EquipmentSlot) EventFactory(net.glowstone.EventFactory) GlowLivingEntity(net.glowstone.entity.GlowLivingEntity) Material(org.bukkit.Material) ItemStack(org.bukkit.inventory.ItemStack) Vector(org.bukkit.util.Vector) PlayerInteractEntityEvent(org.bukkit.event.player.PlayerInteractEntityEvent)

Example 18 with GlowEntity

use of net.glowstone.entity.GlowEntity in project Glowstone by GlowstoneMC.

the class PlayerUpdateHandler method handle.

@Override
public void handle(GlowSession session, PlayerUpdateMessage message) {
    GlowPlayer player = session.getPlayer();
    Location oldLocation = player.getLocation();
    Location newLocation = oldLocation.clone();
    message.update(newLocation);
    // don't let players reach an illegal position
    if (Math.abs(newLocation.getBlockX()) > 32000000 || Math.abs(newLocation.getBlockZ()) > 32000000) {
        session.getPlayer().kickPlayer("Illegal position");
        return;
    }
    /*
          don't let players move more than 100 blocks in a single packet
          if they move greater than 10 blocks, but less than 100, just warn
          this is NOT robust hack prevention - only to prevent client
          confusion about where its actual location is (e.g. during login)
        */
    if (message.moved() && !player.isDead()) {
        if (player.teleportedTo != null) {
            if (newLocation.equals(player.teleportedTo)) {
                player.endTeleport();
                return;
            } else {
                // outdated location, so skip packet
                return;
            }
        } else {
            double distance = newLocation.distanceSquared(oldLocation);
            if (distance > 100 * 100) {
                player.kickPlayer("You moved too quickly :( (Hacking?)");
                return;
            } else if (distance > 100) {
                GlowServer.logger.warning(player.getName() + " moved too quickly!");
            }
        }
    }
    // call move event if movement actually occurred and there are handlers registered
    if (!oldLocation.equals(newLocation) && PlayerMoveEvent.getHandlerList().getRegisteredListeners().length > 0) {
        PlayerMoveEvent event = EventFactory.getInstance().callEvent(new PlayerMoveEvent(player, oldLocation, newLocation));
        if (event.isCancelled()) {
            // tell client they're back where they started
            session.send(new PositionRotationMessage(oldLocation));
            return;
        }
        if (!event.getTo().equals(newLocation)) {
            // teleport to the set destination: fires PlayerTeleportEvent and
            // handles if the destination is in another world
            player.teleport(event.getTo(), TeleportCause.PLUGIN);
            return;
        }
        if (!Objects.equals(player.getLocation(), oldLocation)) {
            // plugin changed location on move event
            return;
        }
    }
    // move event was not fired or did nothing, simply update location
    player.setRawLocation(newLocation);
    if (Position.hasRotated(oldLocation, newLocation)) {
        player.setHeadYaw(newLocation.getYaw());
    }
    // do stuff with onGround if we need to
    if (player.isOnGround() != message.isOnGround()) {
        if (message.isOnGround() && player.getVelocity().getY() > 0) {
            // jump
            player.incrementStatistic(Statistic.JUMP);
            if (player.isSprinting()) {
                player.addExhaustion(0.2f);
            } else {
                player.addExhaustion(0.05f);
            }
        }
        player.setOnGround(message.isOnGround());
    }
    // Checks if the player is still wearing the Elytra
    ItemStack chestplate = player.getInventory().getChestplate();
    boolean hasElytra = chestplate != null && chestplate.getType() == Material.ELYTRA && chestplate.getDurability() < chestplate.getType().getMaxDurability();
    if (player.isGliding() && (player.isOnGround() || !hasElytra)) {
        player.setGliding(false);
    }
    player.addMoveExhaustion(newLocation);
    // track movement stats
    Vector delta = newLocation.clone().subtract(oldLocation).toVector();
    delta.setX(Math.abs(delta.getX()));
    delta.setY(Math.abs(delta.getY()));
    delta.setZ(Math.abs(delta.getZ()));
    int flatDistance = (int) Math.round(Math.hypot(delta.getX(), delta.getZ()) * 100.0);
    if (flatDistance <= 0) {
        return;
    }
    if (player.isInsideVehicle()) {
        final GlowEntity vehicle = player.getVehicle();
        if (vehicle != null) {
            switch(vehicle.getType()) {
                case BOAT:
                    player.incrementStatistic(Statistic.BOAT_ONE_CM, flatDistance);
                    break;
                case MINECART:
                    player.incrementStatistic(Statistic.MINECART_ONE_CM, flatDistance);
                    break;
                default:
                    break;
            }
        }
    } else if (message.isOnGround()) {
        if (player.isSprinting()) {
            player.incrementStatistic(Statistic.SPRINT_ONE_CM, flatDistance);
        } else if (player.isSneaking()) {
            player.incrementStatistic(Statistic.CROUCH_ONE_CM, flatDistance);
        } else {
            player.incrementStatistic(Statistic.WALK_ONE_CM, flatDistance);
        }
    } else if (player.isFlying()) {
        player.incrementStatistic(Statistic.FLY_ONE_CM, flatDistance);
    } else if (player.isInWater()) {
        player.incrementStatistic(Statistic.SWIM_ONE_CM, flatDistance);
    }
}
Also used : PositionRotationMessage(net.glowstone.net.message.play.game.PositionRotationMessage) GlowPlayer(net.glowstone.entity.GlowPlayer) GlowEntity(net.glowstone.entity.GlowEntity) PlayerMoveEvent(org.bukkit.event.player.PlayerMoveEvent) ItemStack(org.bukkit.inventory.ItemStack) Vector(org.bukkit.util.Vector) Location(org.bukkit.Location)

Example 19 with GlowEntity

use of net.glowstone.entity.GlowEntity in project Glowstone by GlowstoneMC.

the class EntityUtils method refresh.

/**
 * Refreshes the entity for nearby clients.
 *
 * <p>This will first destroy, and then spawn the painting again using its current art and
 * facing value.
 *
 * @param entity the entity to refresh.
 */
public static void refresh(@NotNull GlowEntity entity) {
    final DestroyEntitiesMessage destroyMessage = new DestroyEntitiesMessage(Collections.singletonList(entity.getEntityId()));
    final List<Message> spawnMessages = entity.createSpawnMessage();
    final Message[] messages = new Message[] { destroyMessage, spawnMessages.get(0) };
    entity.getWorld().getRawPlayers().stream().filter(p -> p.canSeeEntity(entity)).forEach(p -> p.getSession().sendAll(messages));
}
Also used : DestroyEntitiesMessage(net.glowstone.net.message.play.entity.DestroyEntitiesMessage) Attribute(org.bukkit.attribute.Attribute) AttributeInstance(org.bukkit.attribute.AttributeInstance) EventFactory(net.glowstone.EventFactory) EntityRegainHealthEvent(org.bukkit.event.entity.EntityRegainHealthEvent) Message(com.flowpowered.network.Message) GlowEntity(net.glowstone.entity.GlowEntity) LivingEntity(org.bukkit.entity.LivingEntity) PotionEffect(org.bukkit.potion.PotionEffect) List(java.util.List) DestroyEntitiesMessage(net.glowstone.net.message.play.entity.DestroyEntitiesMessage) NotNull(org.jetbrains.annotations.NotNull) Collections(java.util.Collections) EntityDamageEvent(org.bukkit.event.entity.EntityDamageEvent) PotionEffectType(org.bukkit.potion.PotionEffectType) Message(com.flowpowered.network.Message) DestroyEntitiesMessage(net.glowstone.net.message.play.entity.DestroyEntitiesMessage)

Aggregations

GlowEntity (net.glowstone.entity.GlowEntity)19 Location (org.bukkit.Location)9 GlowPlayer (net.glowstone.entity.GlowPlayer)8 CompoundTag (net.glowstone.util.nbt.CompoundTag)8 Vector (org.bukkit.util.Vector)7 ArrayList (java.util.ArrayList)6 Entity (org.bukkit.entity.Entity)4 EntityType (org.bukkit.entity.EntityType)4 LivingEntity (org.bukkit.entity.LivingEntity)3 Message (com.flowpowered.network.Message)2 IOException (java.io.IOException)2 Collections (java.util.Collections)2 LinkedList (java.util.LinkedList)2 List (java.util.List)2 ThreadLocalRandom (java.util.concurrent.ThreadLocalRandom)2 EventFactory (net.glowstone.EventFactory)2 BoundingBox (net.glowstone.entity.physics.BoundingBox)2 MojangsonParseException (net.glowstone.util.mojangson.ex.MojangsonParseException)2 ConsoleCommandSender (org.bukkit.command.ConsoleCommandSender)2 ItemStack (org.bukkit.inventory.ItemStack)2