DEADSOFTWARE

Remove seed from default world config
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / world / GameWorld.java
1 package ru.deadsoftware.cavedroid.game.world;
3 import com.badlogic.gdx.utils.Disposable;
4 import com.badlogic.gdx.utils.TimeUtils;
5 import kotlin.Pair;
6 import ru.deadsoftware.cavedroid.game.GameItems;
7 import ru.deadsoftware.cavedroid.game.GameScope;
8 import ru.deadsoftware.cavedroid.game.mobs.FallingGravel;
9 import ru.deadsoftware.cavedroid.game.mobs.FallingSand;
10 import ru.deadsoftware.cavedroid.game.mobs.MobsController;
11 import ru.deadsoftware.cavedroid.game.model.world.generator.WorldGeneratorConfig;
12 import ru.deadsoftware.cavedroid.game.objects.Block;
13 import ru.deadsoftware.cavedroid.game.objects.DropController;
15 import javax.annotation.CheckForNull;
16 import javax.inject.Inject;
17 import java.sql.Time;
18 import java.util.Timer;
20 @GameScope
21 public class GameWorld implements Disposable {
23 private static final int DEFAULT_WIDTH = 1024;
24 private static final int DEFAULT_HEIGHT = 256;
25 private static final int UPDATE_RANGE = 16;
27 private final DropController mDropController;
28 private final MobsController mMobsController;
30 private final Timer mGameFluidsTimer;
31 private final GameFluidsThread mGameFluidsThread;
33 private final int mWidth;
34 private final int mHeight;
35 private final int[][] mForeMap;
36 private final int[][] mBackMap;
38 private boolean mShouldUpdate;
39 private int mUpdateX;
40 private int mUpdateY;
42 @Inject
43 public GameWorld(DropController dropController,
44 MobsController mobsController,
45 @CheckForNull int[][] foreMap,
46 @CheckForNull int[][] backMap) {
47 mDropController = dropController;
48 mMobsController = mobsController;
50 boolean isNewGame = foreMap == null || backMap == null;
52 if (isNewGame) {
53 mWidth = DEFAULT_WIDTH;
54 mHeight = DEFAULT_HEIGHT;
55 Pair<int[][], int[][]> maps = new GameWorldGenerator(WorldGeneratorConfig.Companion.getDefaultWithSeed()).generate();
56 mForeMap = maps.getFirst();
57 mBackMap = maps.getSecond();
58 mMobsController.getPlayer().respawn(this);
59 } else {
60 mForeMap = foreMap;
61 mBackMap = backMap;
62 mWidth = mForeMap.length;
63 mHeight = mForeMap[0].length;
64 }
66 mGameFluidsThread = new GameFluidsThread(this, mMobsController);
68 mGameFluidsTimer = new Timer();
69 mGameFluidsTimer.scheduleAtFixedRate(mGameFluidsThread, 0, GameFluidsThread.FLUID_UPDATE_INTERVAL_MS);
70 }
72 public int getWidth() {
73 return mWidth;
74 }
76 public int getHeight() {
77 return mHeight;
78 }
80 public float getWidthPx() {
81 return mWidth * 16f;
82 }
84 public float getHeightPx() {
85 return mHeight * 16f;
86 }
88 public int[][] getFullForeMap() {
89 return mForeMap;
90 }
92 public int[][] getFullBackMap() {
93 return mBackMap;
94 }
96 private int transformX(int x) {
97 x = x % getWidth();
98 if (x < 0) {
99 x = getWidth() - Math.abs(x);
101 return x;
104 private int getMap(int x, int y, int layer) {
105 int map = 0;
106 try {
107 x = transformX(x);
108 map = (layer == 0) ? mForeMap[x][y] : mBackMap[x][y];
109 } catch (ArrayIndexOutOfBoundsException ignored) {
111 return map;
114 private void setMap(int x, int y, int layer, int value) {
115 try {
116 x = transformX(x);
117 if (layer == 0) {
118 mForeMap[x][y] = value;
119 } else {
120 mBackMap[x][y] = value;
122 } catch (ArrayIndexOutOfBoundsException ignored) {
126 public boolean hasForeAt(int x, int y) {
127 return getMap(x, y, 0) != 0;
130 public boolean hasBackAt(int x, int y) {
131 return getMap(x, y, 1) != 0;
134 public int getForeMap(int x, int y) {
135 return getMap(x, y, 0);
138 public Block getForeMapBlock(int x, int y) {
139 return GameItems.getBlock(getMap(x, y, 0));
142 public void setForeMap(int x, int y, int id) {
143 setMap(x, y, 0, id);
146 public int getBackMap(int x, int y) {
147 return getMap(x, y, 1);
150 public Block getBackMapBlock(int x, int y) {
151 return GameItems.getBlock(getMap(x, y, 1));
154 public void setBackMap(int x, int y, int id) {
155 setMap(x, y, 1, id);
158 private void placeSlab(int x, int y, int value) {
159 switch (value) {
160 case 51:
161 setForeMap(x, y, 52);
162 break;
163 case 53:
164 setForeMap(x, y, 21);
165 break;
166 case 54:
167 setForeMap(x, y, 5);
168 break;
169 case 55:
170 setForeMap(x, y, 4);
171 break;
172 case 56:
173 setForeMap(x, y, 28);
174 break;
175 case 58:
176 setForeMap(x, y, 57);
177 break;
181 public void placeToForeground(int x, int y, int value) {
182 if (!hasForeAt(x, y) || value == 0 || !GameItems.getBlock(getForeMap(x, y)).hasCollision()) {
183 setForeMap(x, y, value);
184 } else if (GameItems.isSlab(value) && getForeMap(x, y) == value) {
185 placeSlab(x, y, value);
187 mUpdateX = x - 8;
188 mUpdateY = y - 8;
189 mShouldUpdate = true;
192 public void placeToBackground(int x, int y, int value) {
193 if (value == 0 || (getBackMap(x, y) == 0 && GameItems.getBlock(value).hasCollision()) &&
194 (!GameItems.getBlock(value).isTransparent() || value == 18)) {
195 setBackMap(x, y, value);
199 public void destroyForeMap(int x, int y) {
200 Block block = GameItems.getBlock(getForeMap(x, y));
201 if (block.hasDrop()) {
202 mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, GameItems.getItemId(block.getDrop()));
204 placeToForeground(x, y, 0);
207 public void destroyBackMap(int x, int y) {
208 Block block = GameItems.getBlock(getBackMap(x, y));
209 if (block.hasDrop()) {
210 mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, GameItems.getItemId(block.getDrop()));
212 placeToBackground(x, y, 0);
215 private void updateBlock(int x, int y) {
216 if (getForeMap(x, y) == 10) {
217 if (!hasForeAt(x, y + 1) || !getForeMapBlock(x, y + 1).hasCollision()) {
218 setForeMap(x, y, 0);
219 mMobsController.addMob(FallingSand.class, x * 16, y * 16);
220 updateBlock(x, y - 1);
224 if (getForeMap(x, y) == 11) {
225 if (!hasForeAt(x, y + 1) || !getForeMapBlock(x, y + 1).hasCollision()) {
226 setForeMap(x, y, 0);
227 mMobsController.addMob(FallingGravel.class, x * 16, y * 16);
228 updateBlock(x, y - 1);
232 if (hasForeAt(x, y) && getForeMapBlock(x, y).requiresBlock()) {
233 if (!hasForeAt(x, y + 1) || !getForeMapBlock(x, y + 1).hasCollision()) {
234 destroyForeMap(x, y);
235 updateBlock(x, y - 1);
239 if (getForeMap(x, y) == 2) {
240 if (hasForeAt(x, y - 1) && (getForeMapBlock(x, y - 1).hasCollision() ||
241 GameItems.isFluid(getForeMap(x, y - 1)))) {
242 setForeMap(x, y, 3);
247 public void update() {
248 if (mShouldUpdate) {
249 for (int y = mUpdateY; y < mUpdateY + UPDATE_RANGE; y++) {
250 for (int x = mUpdateX; x < mUpdateX + UPDATE_RANGE; x++) {
251 updateBlock(x, y);
254 mShouldUpdate = false;
258 @Override
259 public void dispose() {
260 mGameFluidsTimer.cancel();