DEADSOFTWARE

Fix codestyle
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / GameFluidsThread.java
1 package ru.deadsoftware.cavedroid.game;
3 import com.badlogic.gdx.utils.TimeUtils;
5 import java.util.Arrays;
7 import static ru.deadsoftware.cavedroid.GameScreen.GP;
8 import static ru.deadsoftware.cavedroid.game.GameItems.*;
10 class GameFluidsThread extends Thread {
12 private static final int FLUID_UPDATE_INTERVAL_MS = 100;
13 private static final int FLUID_STATES = 5;
15 private static final int[] WATER_IDS = {8, 60, 61, 62, 63};
16 private static final int[] LAVA_IDS = {9, 64, 65, 66, 67};
18 private long fluidLastUpdateTimestamp = 0;
20 private int getBlockState(int id) {
21 return isWater(id) ? Arrays.binarySearch(WATER_IDS, id) : Arrays.binarySearch(LAVA_IDS, id);
22 }
24 private int getNextBlockState(int id) {
25 if (!isFluid(id)) {
26 return -1;
27 }
28 int state = getBlockState(id);
29 if (state < FLUID_STATES - 1) {
30 return state + 1;
31 }
32 return -1;
33 }
35 private int getNextBlockStateId(int id) {
36 int nextState = getNextBlockState(id);
37 if (nextState == -1) {
38 return 0;
39 }
40 if (isWater(id)) {
41 return WATER_IDS[nextState];
42 }
43 return LAVA_IDS[nextState];
44 }
46 private int id(int x, int y) {
47 return GP.world.getForeMap(x, y);
48 }
50 private boolean sameFluid(int thisId, int thatId) {
51 return isFluid(thatId) && isWater(thatId) == isWater(thisId);
52 }
54 private boolean noFluidNearby(int x, int y) {
55 return !isFluid(id(x, y - 1)) &&
56 (!isFluid(id(x - 1, y)) || id(x - 1, y) >= id(x, y)) &&
57 (!isFluid(id(x + 1, y)) || id(x + 1, y) >= id(x, y));
58 }
60 private boolean drainFluid(int x, int y) {
61 if (getBlockState(id(x, y)) > 0) {
62 if (noFluidNearby(x, y)) {
63 GP.world.setForeMap(x, y, getNextBlockStateId(id(x, y)));
64 }
65 if (!isFluid(id(x, y))) {
66 GP.world.setForeMap(x, y, 0);
67 return true;
68 }
69 }
70 return false;
71 }
73 private void flowFluidTo(int thisId, int x, int y, int nextStateId) {
74 int thatId = id(x, y);
75 if (fluidCanFlowThere(thisId, thatId)) {
76 GP.world.setForeMap(x, y, nextStateId);
77 } else if (isWater(thisId) && isLava(thatId)) {
78 if (getBlockState(thatId) > 0) {
79 GP.world.setForeMap(x, y, 4); //cobblestone
80 } else {
81 GP.world.setForeMap(x, y, 68); //obsidian
82 }
83 } else if (isLava(thisId) && isWater(thatId)) {
84 GP.world.setForeMap(x, y, 1); //stone
85 }
86 }
88 private void flowFluid(int x, int y) {
89 int id = id(x, y);
90 if (getBlockState(id) < FLUID_STATES - 1 && getBlock(id(x, y + 1)).hasCollision()) {
91 int nextState = getNextBlockState(id);
92 int nextStateId = getNextBlockStateId(id);
93 if (nextState == 1) {
94 nextStateId++;
95 }
96 flowFluidTo(id, x - 1, y, nextStateId);
97 flowFluidTo(id, x + 1, y, nextStateId);
98 } else {
99 flowFluidTo(id, x, y + 1, isWater(id) ? WATER_IDS[1] : LAVA_IDS[1]);
104 private void updateFluids(int x, int y) {
105 if (!isFluid(id(x, y))) {
106 return;
108 if (drainFluid(x, y)) {
109 return;
111 flowFluid(x, y);
114 private void fluidUpdater() {
115 int midScreen = (int) (GP.renderer.getCamX() + GP.renderer.getWidth() / 2) / 16;
116 for (int y = GP.world.getHeight() - 1; y >= 0; y--) {
117 for (int x = 0; x <= GP.world.getWidth() / 2; x++) {
118 updateFluids(midScreen + x, y);
119 updateFluids(midScreen - x, y);
124 private boolean timeToUpdate() {
125 if (TimeUtils.timeSinceMillis(fluidLastUpdateTimestamp) >= FLUID_UPDATE_INTERVAL_MS) {
126 fluidLastUpdateTimestamp = TimeUtils.millis();
127 return true;
129 return false;
132 @Override
133 public void run() {
134 while (!this.isInterrupted()) {
135 if (timeToUpdate()) {
136 fluidUpdater();