/** * */ package cn.dawn47.misc.entity; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityHanging; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.DamageSource; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import cn.annoreg.core.Registrant; import cn.annoreg.mc.RegEntity; import cn.dawn47.misc.client.RendererPoster; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; /** * 宣传海报的实体 * @author WeathFolD * */ @Registrant @RegEntity @RegEntity.HasRender public class EntityPoster extends EntityHanging { @SideOnly(Side.CLIENT) @RegEntity.Render public static RendererPoster renderer; public static final PosterInfo[] infs = { new PosterInfo(4, 2), new PosterInfo(4, 2), new PosterInfo(4, 2), new PosterInfo(4, 2), new PosterInfo(4, 2) }; public int posterID; //海报ID(0~4 Currently) /* 实际依附的方块坐标(最x- y- z-侧的那个) */ public int attachedX, attachedY, attachedZ; public ForgeDirection attachedSide = ForgeDirection.UNKNOWN; private EntityPoster(World world, int bx, int by, int bz, int side, int id) { super(world); posterID = id; attachedX = bx; attachedY = by; attachedZ = bz; attachedSide = ForgeDirection.values()[side]; updatePosition(); this.hangingDirection = side; this.setSize(1F, 1F); } /** * 客户端构造器 */ public EntityPoster(World world) { super(world); this.setSize(1F, 1F); this.ignoreFrustumCheck = true; } public void initAABB() { double x0 = 0, y0 = 0, z0 = 0, x1 = 0, y1 = 0, z1 = 0; PosterInfo inf = infs[posterID]; switch(attachedSide) { case NORTH: z0 = -0.1; x1 = 1; x0 = 1 - inf.width; y1 = inf.height; z1 = 0.1; break; case SOUTH: z0 = -0.1; x1 = inf.width; y1 = inf.height; z1 = 0.1; break; case EAST: x0 = -0.1; z1 = 1; z0 = 1 - inf.width; y1 = inf.height; x1 = 0.1; break; case WEST: x0 = -0.1; z1 = inf.width; y1 = inf.height; x1 = 0.1; break; default: break; } this.boundingBox.minX = posX + x0; this.boundingBox.minY = posY + y0; this.boundingBox.minZ = posZ + z0; this.boundingBox.maxX = posX + x1; this.boundingBox.maxY = posY + y1; this.boundingBox.maxZ = posZ + z1; } @Override public void entityInit() { this.dataWatcher.addObject(10, Byte.valueOf((byte)0)); //posterID this.dataWatcher.addObject(11, Integer.valueOf(0)); //attachedX this.dataWatcher.addObject(12, Integer.valueOf(0)); //attachedY this.dataWatcher.addObject(13, Integer.valueOf(0)); //attachedZ this.dataWatcher.addObject(14, Byte.valueOf((byte)0)); //side } @Override /** * 愉快的帧更新 */ public void onUpdate() { this.onGround = false; doSync(); //数据同步 updatePosition(); //更新位置 initAABB(); //Update BoundingBox } private void updatePosition() { if(attachedX == 0 && attachedY == 0 && attachedZ == 0) { //State bad, return return; } //强制设置位置,防止MC的同步及检查函数显示设置 lastTickPosX = posX = attachedX + (attachedSide.offsetX != 0 ? (attachedSide.offsetX == 1 ? 1.01 : -0.01) : 0); lastTickPosY = posY = attachedY + 0.01; lastTickPosZ = posZ = attachedZ + (attachedSide.offsetZ != 0 ? (attachedSide.offsetZ == 1 ? 1.01 : -0.01) : 0); } /** * 数据同步工作 */ private void doSync() { if(worldObj.isRemote) { posterID = dataWatcher.getWatchableObjectByte(10); attachedX = dataWatcher.getWatchableObjectInt(11); attachedY = dataWatcher.getWatchableObjectInt(12); attachedZ = dataWatcher.getWatchableObjectInt(13); attachedSide = ForgeDirection.values()[dataWatcher.getWatchableObjectByte(14)]; } else { dataWatcher.updateObject(10, Byte.valueOf((byte)posterID)); dataWatcher.updateObject(11, Integer.valueOf(attachedX)); dataWatcher.updateObject(12, Integer.valueOf(attachedY)); dataWatcher.updateObject(13, Integer.valueOf(attachedZ)); dataWatcher.updateObject(14, Byte.valueOf((byte)this.attachedSide.ordinal())); } } @Override public void readEntityFromNBT(NBTTagCompound nbt) { attachedX = nbt.getInteger("attachedX"); attachedY = nbt.getInteger("attachedY"); attachedZ = nbt.getInteger("attachedZ"); attachedSide = ForgeDirection.values()[nbt.getInteger("side")]; posterID = nbt.getInteger("posterID"); updatePosition(); } @Override public void writeEntityToNBT(NBTTagCompound nbt) { nbt.setInteger("attachedX", attachedX); nbt.setInteger("attachedY", attachedY); nbt.setInteger("attachedZ", attachedZ); nbt.setInteger("side", attachedSide.ordinal()); nbt.setInteger("posterID", posterID); } @Override public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) { if (this.isEntityInvulnerable()) return false; if (!this.isDead && !this.worldObj.isRemote) { this.setDead(); this.setBeenAttacked(); } return true; } /** * 在某空间位置和side生成一个海报实体,若找不到可行的空间位置,返回null */ public static EntityPoster createEntity(World world, int x, int y, int z, int side, int id) { int[] coords = findPosition(world, x, y, z, side); if(coords == null) { return null; } return new EntityPoster(world, coords[0], coords[1], coords[2], side, id); } /** * 自动为海报寻找放置空间(复杂度:O(width*height)) */ static int[] findPosition(World world, int x, int y, int z, int side) { return new int[] { x, y, z }; } @Override public int getWidthPixels() { return 512; } @Override public int getHeightPixels() { return 256; } @Override public void onBroken(Entity var1) {} }