Package Hexel.blocks.rules

Source Code of Hexel.blocks.rules.WatermoveRule

package Hexel.blocks.rules;

import java.util.ArrayList;

import Hexel.blocks.BlockDelta;
import Hexel.blocks.BlockRule;
import Hexel.blocks.BlockRules;
import Hexel.blocks.BlockSimulator;
import Hexel.blocks.BlockSimulator.BlockDeltaAdder;
import Hexel.blocks.BlockTools;
import Hexel.blocks.BlockTools.PointFloodSearchMatcher;
import Hexel.blocks.FreqBlockRule;
import Hexel.blocks.types.Block;
import Hexel.blocks.types.BlockEmpty;
import Hexel.blocks.types.BlockTransparent;
import Hexel.blocks.types.BlockWater;
import Hexel.chunk.Chunk;
import Hexel.chunk.Chunks;
import Hexel.chunk.HighestBlockChunk;
import Hexel.math.HexGeometry;
import Hexel.math.Vector2i;
import Hexel.math.Vector3i;
import Hexel.util.Container;
import Hexel.util.Pair;

public class WatermoveRule extends FreqBlockRule {
  public WatermoveRule() {
    super(5);
  }

  private Vector3i tmp3i = new Vector3i();
  private int numSeen = 0;

  private Container<Vector3i> lowestWaterPoint = new Container<Vector3i>();
  private Container<Integer> lowestWaterLevel = new Container<Integer>();
  private boolean checkAgain;

  @Override
  public int freqRun(int bx, int by, final int bz, boolean fastMode, Block b, final Chunk c,
      HighestBlockChunk hbc, final Chunks chunks, int step, final BlockDeltaAdder blockDeltaAdder) {
    BlockWater bw = (BlockWater)b;
    final Vector3i start = new Vector3i(bx, by, bz);
    checkAgain = false;
    numSeen = 0;
    final int startWaterLevel = bz*8 + bw.getTop();
    lowestWaterLevel.contents = Integer.MAX_VALUE;
    lowestWaterPoint.contents = null;
//    System.out.println("HWG " + step);
    BlockTools.pointFloodSearch(start, new BlockTools.PointFloodSearchMatcher() {
      @Override
      public boolean matches(Vector3i p) {
        Block b = chunks.getBlock(p.x, p.y, p.z, tmp3i, c);
        if (numSeen > 100){
          return false;
        }

//        if (b instanceof BlockEmpty && p.z == bz) {
//          Block bl = chunks.getBlock(p.x, p.y, p.z - 1, tmp3i, c);
//          if (bl instanceof BlockEmpty || bl instanceof BlockWater) {
//            b = bl;
//            p.z -= 1;
//          }
//        }

        int waterLevel;
        if (b instanceof BlockWater || b instanceof BlockEmpty){
          if (b instanceof BlockWater){
            numSeen += 1;
            int blockWaterLevel = 0;
            BlockWater wb = (BlockWater) b;
            if (wb.getBottom() != 0){
              blockWaterLevel = wb.getBottom();
            }
            else if (wb.getTop() < 8) {
              blockWaterLevel = wb.getTop();
            }
            waterLevel = p.z*8 + blockWaterLevel;
          }
          else {
            waterLevel = p.z*8;
          }
          if (startWaterLevel > waterLevel){
            if (!blockDeltaAdder.hasBlockDelta(p)){
              if (lowestWaterPoint.contents == null){
                lowestWaterPoint.contents = p;
                lowestWaterLevel.contents = waterLevel;
              }
              else if (waterLevel < lowestWaterLevel.contents){
                lowestWaterPoint.contents = p;
                lowestWaterLevel.contents = waterLevel;
              }
              else if (waterLevel == lowestWaterLevel.contents){
                double currDist = lowestWaterPoint.contents.distance(start);
                double nextDist = p.distance(start);
                if (nextDist < currDist){
                  lowestWaterPoint.contents = p;
                  lowestWaterLevel.contents = waterLevel;
                }
              }
            }
            else {
              checkAgain = true;
            }
            if (b instanceof BlockWater)
              return true;
          }
        }
        return false;
      }
    });

    if (lowestWaterPoint.contents != null){
      BlockTransparent lowestWaterBlock = (BlockTransparent)chunks.getBlock(
          lowestWaterPoint.contents.x,
          lowestWaterPoint.contents.y,
          lowestWaterPoint.contents.z, tmp3i, c);
      int waterLevelDiff = startWaterLevel - lowestWaterLevel.contents;
      int toMove = Math.min(waterLevelDiff/2, bw.getTop() - bw.getBottom());
      if (toMove > 0){
        if (toMove == bw.getTop() - bw.getBottom()){
          blockDeltaAdder.addBlockDelta(BlockDelta.Aquire(bx, by, bz, BlockEmpty.Make(bw.naturalLightLevel),
              chunks.getStepsToSim(bx, by, bz, tmp3i, c)));
        }
        else {
          blockDeltaAdder.addBlockDelta(BlockDelta.Aquire(bx, by, bz,
              BlockWater.Make(bw.naturalLightLevel, 0, (bw.getTop() - bw.getBottom()) - toMove),
              chunks.getStepsToSim(bx, by, bz, tmp3i, c)));
        }
        blockDeltaAdder.addBlockDelta(BlockDelta.Aquire(
            lowestWaterPoint.contents.x,
            lowestWaterPoint.contents.y,
            lowestWaterPoint.contents.z,
            BlockWater.Make(lowestWaterBlock.naturalLightLevel, 0, toMove),
            chunks.getStepsToSim(bx, by, bz, tmp3i, c)));
      }
    }
    if (checkAgain)
      return 1;
    else
      return BlockSimulator.DONT_RUN;
  }
}
TOP

Related Classes of Hexel.blocks.rules.WatermoveRule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.