package net.fourbytes.shadow.blocks; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import net.fourbytes.shadow.*; import net.fourbytes.shadow.entities.Player; import net.fourbytes.shadow.map.IsSaveable; public abstract class BlockFluid extends BlockType { /*Conor-ian water system. Powered by Conor's redstone brain!*/ public static boolean conor = true; @IsSaveable public Vector2 sourcepos; public float subframe = -1f/60f; public int frame = 0; public float gframe = 24f/60f; public float pframe = 20f/60f; @IsSaveable public int height = 16; public boolean topblock = true; public BlockFluid() { } @Override public void init() { tickAlways = true; solid = false; alpha = 0.75f; rendertop = 0x01; } @Override public void tick(float delta) { if (0f > subframe) { subframe += delta * MathUtils.random(0.1f); return; } subframe += delta * MathUtils.random(0.1f); if (0f > subframe || subframe > 24f/60f) { if (sourcepos != null && conor) { if (hasThisFluid(sourcepos)) { height-=3; if (sourcepos.y < pos.y) { height-=3; } } texupdate = true; } if (height <= 2) { layer.remove(this); } } Array<Block> al = layer.get(Coord.get(pos.x, pos.y)); if (al != null) { for (int i = 0; i < al.size; i++) { Block b = al.items[i]; if (b == this) { continue; } if (b instanceof BlockFluid || b.solid) { layer.remove(this); return; } } } topblock = true; al = layer.get(Coord.get(pos.x, pos.y-1)); if (al != null) { for (int i = 0; i < al.size; i++) { Block b = al.items[i]; if (b instanceof BlockFluid) { height = 16; texupdate = true; topblock = false; } if (b.solid) { topblock = false; break; } } } gframe -= delta; if (gframe <= 0) { boolean free = update(0f, 1f, 16, true); if (free) { gframe = 24f/60f; } } pframe -= delta; boolean onground = false; al = layer.get(Coord.get(pos.x, pos.y+1)); if (al != null) { for (int i = 0; i < al.size; i++) { Block b = al.items[i]; if (b instanceof BlockFluid) { onground = false; texupdate = true; break; } if (b.solid) { onground = true; texupdate = true; break; } //if (!free) break; } } if (pframe <= 0 && height > 4 && onground) { boolean free1 = update(-1f, 0f, height-1, false); boolean free2 = update(1f, 0f, height-1, false); if (free1 && free2) { pframe = 20f/60f; } } rec.height = height/16f; colloffs.y = (16-height)/16f; colloffs.height = -colloffs.y; renderoffs.y = 1f - 1f * (height/16f); } public boolean hasThisFluid(Vector2 pos) { Class<? extends BlockFluid> clazz = getClass(); Array<Block> al = layer.get(Coord.get((int) pos.x, Coord.get1337((int) pos.y))); //TODO Check if 1337 needed for x or not if (al != null) { for (int i = 0; i < al.size; i++) { Block b = al.items[i]; if (b != null && clazz == b.getClass()) { return true; } } } return false; } public boolean update(float xo, float yo, int height, boolean hupdate) { boolean free = true; if (height <= 3) { return !hupdate; } /*if (conor) { height++; }*/ Array<Block> al = layer.get(Coord.get(pos.x+xo, pos.y+yo)); if (al != null) { for (int i = 0; i < al.size; i++) { Block b = al.items[i]; if (b == this) { continue; } if (b instanceof BlockPush) { ((BlockPush)b).push((int) xo, 0); } if (b instanceof BlockFluid) { if (isSameType(b)) { BlockFluid fluid = ((BlockFluid)b); if (pos.x != b.pos.x && pos.y != b.pos.y) { if (hupdate) { fluid.height = height; b.texupdate = true; if (fluid.sourcepos != null) { fluid.sourcepos.set(pos); } } else { if (fluid.height < height) { fluid.height = height; fluid.texupdate = true; if (fluid.sourcepos != null) { fluid.sourcepos.set(pos); } } } } free = false; break; } else { boolean handled = !handleMix((BlockFluid)b); if (handled) { free = false; break; } } } if (!b.solid) continue; free = false; break; //if (!free) break; } } if (free) { Block b = create(pos.x + xo, pos.y + yo, height); layer.add(b); } return free; } public Block create(float x, float y, int height) { BlockFluid b = (BlockFluid) BlockType.getInstance(subtype, x, y, layer); b.tickAlways = true; //b.solid = false; b.height = height; b.sourcepos = new Vector2(pos); return b; } @Override public TextureRegion getTexture(int id) { int height = this.height; //if (height <= 0) height = 1; //if (height > 16) height = 16; if (!topblock && height == 16) { TextureRegion[][] regs = Images.split(getTexture0(), 16, height); if (regs.length > 0) { return regs[0][0]; } else { return Images.getTextureRegion("white"); } } else { TextureRegion[][] regs = Images.split(getTexture1(), 16, height); if (regs.length > 0) { return regs[0][frame]; } else { return Images.getTextureRegion("white"); } } } public abstract TextureRegion getTexture0(); public abstract TextureRegion getTexture1(); @Override public void frame(float delta) { subframe += delta * MathUtils.random(2f/60f); if (subframe > 24f/60f) { frame++; subframe = -1f/60f; } if (frame >= 4) { frame = 0; texupdate = true; } } @Override public void preRender() { super.preRender(); images[0].setScaleY(-1f * (height/16f)); } @Override public void render() { } @Override public void renderTop() { super.render(); } boolean isSameType(Object o) { return getClass().isInstance(o); } public abstract boolean handleMix(BlockFluid type); @Override public void collide(Entity e) { e.movement.scl(0.8f); e.movement.y = 0.01f; if (e instanceof Player) { ((Player)e).canJump = ((Player)e).maxJump; if (Input.down.isDown) { e.movement.y = 0.14f; } if (Input.up.isDown) { e.movement.y = -0.14f; } } } }