DEADSOFTWARE

Add use item actions module
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / world / GameFluidsThread.java
1 package ru.deadsoftware.cavedroid.game.world;
3 import com.badlogic.gdx.utils.Timer;
4 import ru.deadsoftware.cavedroid.game.mobs.MobsController;
6 import java.util.Arrays;
8 import static ru.deadsoftware.cavedroid.game.GameItems.*;
10 class GameFluidsThread extends Timer.Task {
12 public static final float FLUID_UPDATE_INTERVAL_SEC = 0.1f;
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 mFluidLastUpdateTimestamp = 0;
20 private final GameWorld mGameWorld;
21 private final MobsController mMobsController;
23 GameFluidsThread(GameWorld gameWorld,
24 MobsController mobsController) {
25 mGameWorld = gameWorld;
26 mMobsController = mobsController;
27 }
29 private int getBlockState(int id) {
30 return isWater(id) ? Arrays.binarySearch(WATER_IDS, id) : Arrays.binarySearch(LAVA_IDS, id);
31 }
33 private int getNextBlockState(int id) {
34 if (!isFluid(id)) {
35 return -1;
36 }
37 int state = getBlockState(id);
38 if (state < FLUID_STATES - 1) {
39 return state + 1;
40 }
41 return -1;
42 }
44 private int getNextBlockStateId(int id) {
45 int nextState = getNextBlockState(id);
46 if (nextState == -1) {
47 return 0;
48 }
49 if (isWater(id)) {
50 return WATER_IDS[nextState];
51 }
52 return LAVA_IDS[nextState];
53 }
55 private int id(int x, int y) {
56 return mGameWorld.getForeMap(x, y);
57 }
59 private boolean sameFluid(int thisId, int thatId) {
60 return isFluid(thatId) && isWater(thatId) == isWater(thisId);
61 }
63 private boolean noFluidNearby(int x, int y) {
64 return !isFluid(id(x, y - 1)) &&
65 (!isFluid(id(x - 1, y)) || id(x - 1, y) >= id(x, y)) &&
66 (!isFluid(id(x + 1, y)) || id(x + 1, y) >= id(x, y));
67 }
69 private boolean drainFluid(int x, int y) {
70 if (getBlockState(id(x, y)) > 0) {
71 if (noFluidNearby(x, y)) {
72 mGameWorld.setForeMap(x, y, getNextBlockStateId(id(x, y)));
73 }
74 if (!isFluid(id(x, y))) {
75 mGameWorld.setForeMap(x, y, 0);
76 return true;
77 }
78 }
79 return false;
80 }
82 private void flowFluidTo(int thisId, int x, int y, int nextStateId) {
83 int thatId = id(x, y);
84 if (fluidCanFlowThere(thisId, thatId)) {
85 mGameWorld.setForeMap(x, y, nextStateId);
86 } else if (isWater(thisId) && isLava(thatId)) {
87 if (getBlockState(thatId) > 0) {
88 mGameWorld.setForeMap(x, y, 4); //cobblestone
89 } else {
90 mGameWorld.setForeMap(x, y, 68); //obsidian
91 }
92 } else if (isLava(thisId) && isWater(thatId)) {
93 mGameWorld.setForeMap(x, y, 1); //stone
94 }
95 }
97 private void flowFluid(int x, int y) {
98 int id = id(x, y);
99 if (getBlockState(id) < FLUID_STATES - 1 && getBlock(id(x, y + 1)).hasCollision()) {
100 int nextState = getNextBlockState(id);
101 int nextStateId = getNextBlockStateId(id);
102 if (nextState == 1) {
103 nextStateId++;
105 flowFluidTo(id, x - 1, y, nextStateId);
106 flowFluidTo(id, x + 1, y, nextStateId);
107 } else {
108 flowFluidTo(id, x, y + 1, isWater(id) ? WATER_IDS[1] : LAVA_IDS[1]);
113 private void updateFluids(int x, int y) {
114 if (!isFluid(id(x, y))) {
115 return;
117 if (drainFluid(x, y)) {
118 return;
120 flowFluid(x, y);
123 private void fluidUpdater() {
124 int midScreen = (int) mMobsController.getPlayer().x / 16;
125 for (int y = mGameWorld.getHeight() - 1; y >= 0; y--) {
126 for (int x = 0; x <= mGameWorld.getWidth() / 2; x++) {
127 updateFluids(midScreen + x, y);
128 updateFluids(midScreen - x, y);
133 @Override
134 public void run() {
135 fluidUpdater();