DEADSOFTWARE

Update README
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / world / GameWorld.java
1 package ru.deadsoftware.cavedroid.game.world;
3 import kotlin.Pair;
4 import ru.deadsoftware.cavedroid.game.GameItemsHolder;
5 import ru.deadsoftware.cavedroid.game.GameScope;
6 import ru.deadsoftware.cavedroid.game.mobs.MobsController;
7 import ru.deadsoftware.cavedroid.game.model.block.Block;
8 import ru.deadsoftware.cavedroid.game.model.item.InventoryItem;
9 import ru.deadsoftware.cavedroid.game.model.item.Item;
10 import ru.deadsoftware.cavedroid.game.model.world.generator.WorldGeneratorConfig;
11 import ru.deadsoftware.cavedroid.game.objects.DropController;
12 import ru.deadsoftware.cavedroid.misc.utils.MeasureUnitsUtilsKt;
14 import javax.annotation.CheckForNull;
15 import javax.inject.Inject;
17 @GameScope
18 public class GameWorld {
20 private final DropController mDropController;
21 private final MobsController mMobsController;
22 private final GameItemsHolder mGameItemsHolder;
24 private final int mWidth;
25 private final int mHeight;
26 private final Block[][] mForeMap;
27 private final Block[][] mBackMap;
29 private final WorldGeneratorConfig mWorldConfig = WorldGeneratorConfig.Companion.getDefault();
31 @Inject
32 public GameWorld(DropController dropController,
33 MobsController mobsController,
34 GameItemsHolder gameItemsHolder,
35 @CheckForNull Block[][] foreMap,
36 @CheckForNull Block[][] backMap) {
37 mDropController = dropController;
38 mMobsController = mobsController;
39 mGameItemsHolder = gameItemsHolder;
41 boolean isNewGame = foreMap == null || backMap == null;
43 if (isNewGame) {
44 mWidth = mWorldConfig.getWidth();
45 mHeight = mWorldConfig.getHeight();
46 Pair<Block[][], Block[][]> maps = new GameWorldGenerator(mWorldConfig, mGameItemsHolder).generate();
47 mForeMap = maps.getFirst();
48 mBackMap = maps.getSecond();
49 mMobsController.getPlayer().respawn(this, mGameItemsHolder);
50 } else {
51 mForeMap = foreMap;
52 mBackMap = backMap;
53 mWidth = mForeMap.length;
54 mHeight = mForeMap[0].length;
55 }
56 }
58 public int getWidth() {
59 return mWidth;
60 }
62 public int getHeight() {
63 return mHeight;
64 }
66 /**
67 * @deprecated for kotlin use {@link MeasureUnitsUtilsKt#getPx } extension val
68 */
69 @Deprecated
70 public float getWidthPx() {
71 return MeasureUnitsUtilsKt.getPx(mWidth);
72 }
74 /**
75 * @deprecated for kotlin use {@link MeasureUnitsUtilsKt#getPx } extension val
76 */
77 @Deprecated
78 public float getHeightPx() {
79 return MeasureUnitsUtilsKt.getPx(mHeight);
80 }
82 public Block[][] getFullForeMap() {
83 return mForeMap;
84 }
86 public Block[][] getFullBackMap() {
87 return mBackMap;
88 }
90 private int transformX(int x) {
91 x = x % getWidth();
92 if (x < 0) {
93 x = getWidth() - Math.abs(x);
94 }
95 return x;
96 }
98 private Block getMap(int x, int y, int layer) {
99 Block map = mGameItemsHolder.getFallbackBlock();
100 try {
101 x = transformX(x);
102 map = (layer == 0) ? mForeMap[x][y] : mBackMap[x][y];
103 } catch (ArrayIndexOutOfBoundsException ignored) {
105 return map;
108 private void setMap(int x, int y, int layer, Block value) {
109 try {
110 x = transformX(x);
111 if (layer == 0) {
112 mForeMap[x][y] = value;
113 } else {
114 mBackMap[x][y] = value;
116 } catch (ArrayIndexOutOfBoundsException ignored) {
120 private boolean isSameSlab(Block slab1, Block slab2) {
121 if (!(slab1 instanceof Block.Slab) || !(slab2 instanceof Block.Slab)) {
122 return false;
125 return slab1.getParams().getKey().equals(((Block.Slab) slab2).getOtherPartBlockKey())
126 || slab1.getParams().getKey().equals(slab2.getParams().getKey());
129 public boolean hasForeAt(int x, int y) {
130 return getMap(x, y, 0) != mGameItemsHolder.getFallbackBlock();
133 public boolean hasBackAt(int x, int y) {
134 return getMap(x, y, 1) != mGameItemsHolder.getFallbackBlock();
137 public Block getForeMap(int x, int y) {
138 return getMap(x, y, 0);
141 public void setForeMap(int x, int y, Block block) {
142 setMap(x, y, 0, block);
145 public void resetForeMap(int x, int y) {
146 setForeMap(x, y, mGameItemsHolder.getFallbackBlock());
149 public Block getBackMap(int x, int y) {
150 return getMap(x, y, 1);
153 public void setBackMap(int x, int y, Block block) {
154 setMap(x, y, 1, block);
157 public boolean placeToForeground(int x, int y, Block value) {
158 if (!hasForeAt(x, y) || value == mGameItemsHolder.getFallbackBlock() || !getForeMap(x, y).hasCollision()) {
159 setForeMap(x, y, value);
160 return true;
161 } else if (value instanceof Block.Slab && isSameSlab(value, getForeMap(x, y))) {
162 setForeMap(x, y, mGameItemsHolder.getBlock(((Block.Slab) value).getFullBlockKey()));
163 return true;
165 return false;
168 public boolean placeToBackground(int x, int y, Block value) {
169 if (value == mGameItemsHolder.getFallbackBlock() || (getBackMap(x, y) == mGameItemsHolder.getFallbackBlock() && value.hasCollision()) &&
170 (!value.isTransparent() || value == mGameItemsHolder.getBlock("glass"))) {
171 setBackMap(x, y, value);
172 return true;
174 return false;
177 private void playerDurateTool() {
178 final InventoryItem playerCurrentItem = mMobsController.getPlayer().getCurrentItem();
179 if (mMobsController.getPlayer().getCurrentItem().getItem().isTool()) {
180 mMobsController.getPlayer().decreaseCurrentItemCount(mGameItemsHolder);
184 private boolean shouldDrop(Block block) {
185 final Item item = mMobsController.getPlayer().getCurrentItem().getItem();
186 int toolLevel = item.isTool() ? ((Item.Tool)item).getLevel() : 0;
187 if (item.isTool() && block.getParams().getToolType() != item.getClass()) {
188 toolLevel = 0;
190 return toolLevel >= block.getParams().getToolLevel();
193 public void destroyForeMap(int x, int y) {
194 Block block = getForeMap(x, y);
195 if (block.hasDrop() && shouldDrop(block)) {
196 for (int i = 0; i < block.getParams().getDropInfo().getCount(); i++) {
197 mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, mGameItemsHolder.getItem(block.getDrop()));
200 playerDurateTool();
201 placeToForeground(x, y, mGameItemsHolder.getFallbackBlock());
204 public WorldGeneratorConfig getWorldConfig() {
205 return mWorldConfig;
208 public void destroyBackMap(int x, int y) {
209 Block block = getBackMap(x, y);
210 if (block.hasDrop() && shouldDrop(block)) {
211 for (int i = 0; i < block.getParams().getDropInfo().getCount(); i++) {
212 mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, mGameItemsHolder.getItem(block.getDrop()));
215 playerDurateTool();
216 placeToBackground(x, y, mGameItemsHolder.getFallbackBlock());