/* * This file is part of NeptuneVanilla, licensed under the MIT License (MIT). * * Copyright (c) 2015-2017, Jamie Mansfield <https://github.com/jamierocks> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.neptunepowered.vanilla.mixin.minecraft.entity; import co.aikar.timings.NeptuneTimings; import co.aikar.timings.Timing; import net.canarymod.api.BoundingBox; import net.canarymod.api.entity.Entity; import net.canarymod.api.entity.EntityItem; import net.canarymod.api.entity.EntityType; import net.canarymod.api.inventory.Item; import net.canarymod.api.nbt.BaseTag; import net.canarymod.api.nbt.CompoundTag; import net.canarymod.api.world.World; import net.canarymod.api.world.position.Location; import net.canarymod.api.world.position.Position; import net.canarymod.api.world.position.Vector3D; import net.minecraft.entity.DataWatcher; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; import org.neptunepowered.vanilla.interfaces.minecraft.entity.IMixinEntity; import org.neptunepowered.vanilla.util.NbtConstants; import org.spongepowered.asm.mixin.Implements; import org.spongepowered.asm.mixin.Interface; import org.spongepowered.asm.mixin.Intrinsic; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.List; import java.util.Random; import java.util.UUID; @Mixin(net.minecraft.entity.Entity.class) @Implements(@Interface(iface = Entity.class, prefix = "entity$")) public abstract class MixinEntity implements Entity, IMixinEntity { @Shadow public double posX; @Shadow public double posY; @Shadow public double posZ; @Shadow public double motionX; @Shadow public double motionY; @Shadow public double motionZ; @Shadow public float rotationPitch; @Shadow public float rotationYaw; @Shadow public boolean preventEntitySpawning; @Shadow public net.minecraft.world.World worldObj; @Shadow public net.minecraft.entity.Entity riddenByEntity; @Shadow public net.minecraft.entity.Entity ridingEntity; @Shadow public boolean onGround; @Shadow public boolean isDead; @Shadow protected boolean isInWeb; @Shadow protected UUID entityUniqueID; @Shadow private int entityId; @Shadow private AxisAlignedBB boundingBox; @Shadow protected DataWatcher dataWatcher; @Shadow protected Random rand; @Shadow public double lastTickPosX; @Shadow public double lastTickPosY; @Shadow public double lastTickPosZ; @Shadow public float prevRotationYaw; @Shadow public float prevRotationPitch; protected NBTTagCompound metadata = new NBTTagCompound(); protected NBTTagCompound bukkitData = new NBTTagCompound(); private Timing timing; @Shadow public abstract void moveEntity(double x, double y, double z); @Shadow public abstract void setDead(); @Shadow protected abstract boolean getFlag(int flag); @Shadow public abstract float getEyeHeight(); @Shadow public abstract boolean isSprinting(); @Shadow public abstract void setSprinting(boolean sprinting); @Shadow public abstract boolean isSneaking(); @Shadow public abstract void setSneaking(boolean sneaking); @Shadow public abstract boolean isInvisible(); @Shadow public abstract void setInvisible(boolean invisible); @Shadow public abstract boolean isInWater(); @Shadow public abstract boolean isInLava(); @Shadow public abstract String getName(); @Shadow public abstract void writeToNBT(NBTTagCompound tagCompound); @Shadow public abstract void readFromNBT(NBTTagCompound tagCompound); @Shadow public abstract boolean isSilent(); @Shadow public void onUpdate() { throw new RuntimeException("noop"); } @Inject(method = "Lnet/minecraft/entity/Entity;writeToNBT(Lnet/minecraft/nbt/NBTTagCompound;)V", at = @At("HEAD")) public void onWriteToNBT(NBTTagCompound tagCompound, CallbackInfo ci) { if (tagCompound.hasKey(NbtConstants.BUKKIT_TAG)) { this.bukkitData = tagCompound.getCompoundTag(NbtConstants.BUKKIT_TAG); } this.writeCanaryNBT(tagCompound); } @Inject(method = "Lnet/minecraft/entity/Entity;readFromNBT(Lnet/minecraft/nbt/NBTTagCompound;)V", at = @At("RETURN")) public void onReadFromNBT(NBTTagCompound tagCompound, CallbackInfo ci) { this.readCanaryNBT(tagCompound); } @Override public double getX() { return posX; } @Override public void setX(int x) { this.posX = x; } @Override public void setX(double x) { this.posX = x; } @Override public double getY() { return posY; } @Override public void setY(int y) { this.posY = y; } @Override public void setY(double y) { this.posY = y; } @Override public double getZ() { return posZ; } @Override public void setZ(int z) { this.posZ = z; } @Override public void setZ(double z) { this.posZ = z; } @Override public double getMotionX() { return motionX; } @Override public void setMotionX(double motionX) { this.motionX = motionX; } @Override public double getMotionY() { return motionY; } @Override public void setMotionY(double motionY) { this.motionY = motionY; } @Override public double getMotionZ() { return motionZ; } @Override public void setMotionZ(double motionZ) { this.motionZ = motionZ; } @Override public float getPitch() { return rotationPitch; } @Override public void setPitch(float pitch) { this.rotationPitch = pitch; } @Override public float getRotation() { return rotationYaw; } @Override public void setRotation(float rotation) { this.rotationYaw = rotation; } @Override public Position getPosition() { return new Position(getX(), getY(), getZ()); } @Override public Location getLocation() { return new Location(getWorld(), getX(), getY(), getZ(), getPitch(), getRotation()); } @Intrinsic public float entity$getEyeHeight() { return this.getEyeHeight(); } @Override public int getID() { return this.entityId; } @Override public UUID getUUID() { return this.entityUniqueID; } @Override public Vector3D getMotion() { return new Vector3D(this.motionX, this.motionY, this.motionZ); } @Override public Vector3D getForwardVector() { return Vector3D.forward; } @Override public void translate(Vector3D factor) { this.setX(this.getX() + factor.getX()); this.setY(this.getY() + factor.getY()); this.setZ(this.getZ() + factor.getZ()); } @Intrinsic public void entity$moveEntity(double motionX, double motionY, double motionZ) { this.moveEntity(motionX, motionY, motionZ); } @Override public void teleportTo(double x, double y, double z) { } @Override public void teleportTo(double x, double y, double z, World world) { } @Override public void teleportTo(double x, double y, double z, float pitch, float rotation) { } @Override public void teleportTo(double x, double y, double z, float pitch, float rotation, World dim) { } @Override public void teleportTo(Location location) { } @Override public void teleportTo(Position position) { } @Override public World getWorld() { return (World) worldObj; } @Intrinsic public boolean entity$isSprinting() { return this.isSprinting(); } @Intrinsic public void entity$setSprinting(boolean sprinting) { this.setSprinting(sprinting); } @Intrinsic public boolean entity$isSneaking() { return this.isSneaking(); } @Intrinsic public void entity$setSneaking(boolean sneaking) { this.setSneaking(sneaking); } @Override public int getFireTicks() { return 0; } @Override public void setFireTicks(int ticks) { } @Override public boolean isLiving() { return false; } @Override public boolean isItem() { return false; } @Override public boolean isMob() { return false; } @Override public boolean isAnimal() { return false; } @Override public boolean isPlayer() { return false; } @Override public boolean isGolem() { return false; } @Override public boolean isNPC() { return false; } @Override public EntityItem dropLoot(int itemId, int amount) { return null; } @Override public EntityItem dropLoot(Item item) { return null; } @Intrinsic public String entity$getName() { return this.getName(); } @Override public boolean canSpawn() { return !preventEntitySpawning; } @Override public boolean spawn() { return false; } @Override public boolean spawn(Entity rider) { return false; } @Override public boolean isRiding() { return false; } @Override public boolean isRidden() { return false; } @Override public Entity getRiding() { return (Entity) riddenByEntity; } @Override public Entity getRider() { return (Entity) ridingEntity; } @Override public void setRider(Entity rider) { this.ridingEntity = (net.minecraft.entity.Entity) rider; } @Override public void mount(Entity entity) { this.riddenByEntity = (net.minecraft.entity.Entity) entity; } @Override public void dismount() { } @Override public void destroy() { this.setDead(); } @Override public boolean isDead() { return this.isDead; } @Override public CompoundTag getNBT() { NBTTagCompound tag = new NBTTagCompound(); this.writeToNBT(tag); return (CompoundTag) tag; } @Override public void setNBT(BaseTag tag) { this.readFromNBT((NBTTagCompound) tag); } @Intrinsic public boolean entity$isInvisible() { return this.isInvisible(); } @Intrinsic public void entity$setInvisible(boolean invisible) { this.setInvisible(invisible); } @Override public CompoundTag getMetaData() { return (CompoundTag) this.metadata; } @Override public boolean isAmbient() { return false; } @Override public boolean isOnGround() { return this.onGround; } @Override public boolean isInWeb() { return isInWeb; } @Intrinsic public boolean entity$isInWater() { return this.isInWater(); } @Intrinsic public boolean entity$isInLava() { return this.isInLava(); } @Override public boolean hasDisplayName() { return false; } @Override public String getDisplayName() { return null; } @Override public void setDisplayName(String display) { } @Override public boolean showingDisplayName() { return false; } @Override public void setShowDisplayName(boolean show) { } @Override public boolean isEating() { return getFlag(4); } @Override public List<Entity> getNearbyEntities(double radius) { return null; } @Override public List<Entity> getNearbyEntities(Vector3D vector) { return null; } @Override public List<Entity> getNearbyEntities(double radius, EntityType... filter) { return null; } @Override public List<Entity> getNearbyEntities(Vector3D vector, EntityType... filter) { return null; } @Override public BoundingBox getBoundingBox() { return (BoundingBox) this.boundingBox; } public NBTTagCompound writeCanaryNBT(NBTTagCompound tagCompound) { // tagCompound.setString("LevelName", this.getWorld().getName()); // TODO: multiworld tagCompound.setTag(NbtConstants.CANARY_TAG, this.metadata); return tagCompound; } public void readCanaryNBT(NBTTagCompound tagCompound) { if (tagCompound.hasKey(NbtConstants.CANARY_TAG)) { this.metadata = tagCompound.getCompoundTag(NbtConstants.CANARY_TAG); } else { this.initializeMetaData(); } } public void initializeMetaData() { } @Override public Timing getTimingsHandler() { if (this.timing == null) { this.timing = NeptuneTimings.getEntityTiming(this); } return this.timing; } @Override public String getFqName() { return "GenericEntity"; } @Override public EntityType getEntityType() { return EntityType.GENERIC_ENTITY; } }