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);
}
}
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());
}
}
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);
}
}
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));
}
Aggregations