package projectzombie.entity; import bdf.types.BdfNamedList; import bdf.types.BdfObject; import gl_engine.MathHelpers; import gl_engine.vec.Vec3d; import projectzombie.model.ModelItem; import projectzombie.util.math.ItemStack; import projectzombie.world.chunk.Chunk; import projectzombie.world.layer.Layer; public class EntityItem extends EntityParticle { private ItemStack stack; private int pickup_time = 200; private long age = 0; public EntityItem(BdfObject bdf) { super(bdf); BdfClassLoad(bdf); } @Override public void BdfClassLoad(BdfObject bdf) { super.BdfClassLoad(bdf); BdfNamedList nl = bdf.getNamedList(); stack = new ItemStack(nl.get("stack")); pickup_time = nl.get("pickup").getInteger(); age = nl.get("age").getLong(); } @Override public void BdfClassSave(BdfObject bdf) { super.BdfClassSave(bdf); BdfNamedList nl = bdf.getNamedList(); stack.BdfClassSave(nl.get("stack")); nl.set("pickup", bdf.newObject().setInteger(pickup_time)); nl.set("age", bdf.newObject().setLong(age)); } public EntityItem(Vec3d pos, Vec3d velocity, ItemStack stack, double angle) { super(pos, velocity); this.emitsLight = true; this.stack = stack; push(MathHelpers.moveTowards2(0.05, angle).xny().add(new Vec3d(0, 0.1, 0))); } public EntityItem(Vec3d pos, Vec3d velocity, ItemStack stack) { this(pos, velocity, stack, rand.nextDouble() * MathHelpers.TWO_PI); } @Override public double getLightLevel() { if(this.stack.isEmpty()) return 0; return getLightWithHeight(this.stack.item.getLightLevel()); } @Override public void tick(Chunk chunk, Layer layer) { super.tick(chunk, layer); age += 1; pickup_time -= 1; // Merge nearby stacks for(Entity e : layer.getNearbyEntities(getPos().xz(), 2)) { if(e instanceof EntityItem && e != this) { EntityItem ei = (EntityItem) e; if( ei.stack.meta == this.stack.meta && ei.stack.item == this.stack.item && ei.stack.count + this.stack.count <= this.stack.item.max && ei.age > this.age ) { if(ei.getPos().squareDistance(getPos()) < 0.1) { this.pickup_time = 200; this.stack.count += ei.stack.count; setPos(ei.getPos().divide(2).add(getPos().divide(2))); setVelocity(ei.getVelocity().divide(2).add(getVelocity().divide(2))); ei.kill(); } else { push(ei.getPos().subtract(getPos()).normalize().multiply(0.001)); } } } if(pickup_time <= 0 && e instanceof EntityHasInventory) { if(e.getPos().squareDistance(getPos()) < 0.5) { stack.item.onPickedUp(stack, layer, chunk, e); } else { push(e.getPos().subtract(getPos()).normalize().multiply(0.05)); } } } // Kill this entity if the stack is empty if(stack.isEmpty()) { kill(); return; } } @Override public boolean shouldKillParticle() { return false; } @Override public EntityParticlePart getParticleAt(int id) { ModelItem model = stack.item.getModel(stack.meta); EntityParticlePart particle = new EntityParticlePart(model.tex, getPos().add(new Vec3d(0, 0.25, 0)), 0.5, 0b1000); particle.animationSize = model.animationSize; particle.animationSpeed = model.animationSpeed; return particle; } @Override public int getParticleCount() { return 1; } }