DEADSOFTWARE

Add chest
[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.container.Container;
12 import ru.deadsoftware.cavedroid.game.objects.drop.DropController;
13 import ru.deadsoftware.cavedroid.game.objects.container.Furnace;
14 import ru.deadsoftware.cavedroid.game.objects.container.ContainerController;
15 import ru.deadsoftware.cavedroid.misc.utils.MeasureUnitsUtilsKt;
17 import javax.annotation.CheckForNull;
18 import javax.inject.Inject;
20 @GameScope
21 public class GameWorld {
23 private static final int FOREGROUND_Z = 0;
24 private static final int BACKGROUND_Z = 1;
26 private final DropController mDropController;
27 private final MobsController mMobsController;
28 private final GameItemsHolder mGameItemsHolder;
29 private final ContainerController mContainerController;
31 private final int mWidth;
32 private final int mHeight;
33 private final Block[][] mForeMap;
34 private final Block[][] mBackMap;
36 private final WorldGeneratorConfig mWorldConfig = WorldGeneratorConfig.Companion.getDefault();
38 @Inject
39 public GameWorld(DropController dropController,
40 MobsController mobsController,
41 GameItemsHolder gameItemsHolder,
42 ContainerController containerController,
43 @CheckForNull Block[][] foreMap,
44 @CheckForNull Block[][] backMap) {
45 mDropController = dropController;
46 mMobsController = mobsController;
47 mGameItemsHolder = gameItemsHolder;
48 mContainerController = containerController;
50 boolean isNewGame = foreMap == null || backMap == null;
52 if (isNewGame) {
53 mWidth = mWorldConfig.getWidth();
54 mHeight = mWorldConfig.getHeight();
55 Pair<Block[][], Block[][]> maps = new GameWorldGenerator(mWorldConfig, mGameItemsHolder).generate();
56 mForeMap = maps.getFirst();
57 mBackMap = maps.getSecond();
58 mMobsController.getPlayer().respawn(this, mGameItemsHolder);
59 } else {
60 mForeMap = foreMap;
61 mBackMap = backMap;
62 mWidth = mForeMap.length;
63 mHeight = mForeMap[0].length;
64 }
65 }
67 public int getWidth() {
68 return mWidth;
69 }
71 public int getHeight() {
72 return mHeight;
73 }
75 /**
76 * @deprecated for kotlin use {@link MeasureUnitsUtilsKt#getPx } extension val
77 */
78 @Deprecated
79 public float getWidthPx() {
80 return MeasureUnitsUtilsKt.getPx(mWidth);
81 }
83 /**
84 * @deprecated for kotlin use {@link MeasureUnitsUtilsKt#getPx } extension val
85 */
86 @Deprecated
87 public float getHeightPx() {
88 return MeasureUnitsUtilsKt.getPx(mHeight);
89 }
91 public Block[][] getFullForeMap() {
92 return mForeMap;
93 }
95 public Block[][] getFullBackMap() {
96 return mBackMap;
97 }
99 private int transformX(int x) {
100 x = x % getWidth();
101 if (x < 0) {
102 x = getWidth() - Math.abs(x);
104 return x;
107 private Block getMap(int x, int y, int layer) {
108 Block map = mGameItemsHolder.getFallbackBlock();
110 if (y < 0 || y >= getHeight()) {
111 return map;
114 x = transformX(x);
116 if (x < 0 || x >= getWidth()) {
117 return map;
120 map = (layer == 0) ? mForeMap[x][y] : mBackMap[x][y];
122 return map;
125 private void setMap(int x, int y, int layer, Block value) {
126 if (y < 0 || y >= getHeight()) {
127 return;
130 x = transformX(x);
132 if (x < 0 || x >= getWidth()) {
133 return;
136 mContainerController.destroyContainer(x, y, layer, false);
138 if (value.isContainer()) {
139 mContainerController.addContainer(x, y, layer, (Class<? extends Block.Container>) value.getClass());
142 if (layer == 0) {
143 mForeMap[x][y] = value;
144 } else {
145 mBackMap[x][y] = value;
149 private boolean isSameSlab(Block slab1, Block slab2) {
150 if (!(slab1 instanceof Block.Slab) || !(slab2 instanceof Block.Slab)) {
151 return false;
154 return slab1.getParams().getKey().equals(((Block.Slab) slab2).getOtherPartBlockKey())
155 || slab1.getParams().getKey().equals(slab2.getParams().getKey());
158 public boolean hasForeAt(int x, int y) {
159 return getMap(x, y, FOREGROUND_Z) != mGameItemsHolder.getFallbackBlock();
162 public boolean hasBackAt(int x, int y) {
163 return getMap(x, y, BACKGROUND_Z) != mGameItemsHolder.getFallbackBlock();
166 public Block getForeMap(int x, int y) {
167 return getMap(x, y, FOREGROUND_Z);
170 public void setForeMap(int x, int y, Block block) {
171 setMap(x, y, FOREGROUND_Z, block);
174 public void resetForeMap(int x, int y) {
175 setForeMap(x, y, mGameItemsHolder.getFallbackBlock());
178 public Block getBackMap(int x, int y) {
179 return getMap(x, y, BACKGROUND_Z);
182 public void setBackMap(int x, int y, Block block) {
183 setMap(x, y, BACKGROUND_Z, block);
186 public boolean placeToForeground(int x, int y, Block value) {
187 if (!hasForeAt(x, y) || value == mGameItemsHolder.getFallbackBlock() || !getForeMap(x, y).hasCollision()) {
188 setForeMap(x, y, value);
189 return true;
190 } else if (value instanceof Block.Slab && isSameSlab(value, getForeMap(x, y))) {
191 setForeMap(x, y, mGameItemsHolder.getBlock(((Block.Slab) value).getFullBlockKey()));
192 return true;
194 return false;
197 public boolean placeToBackground(int x, int y, Block value) {
198 if (value == mGameItemsHolder.getFallbackBlock() || (getBackMap(x, y) == mGameItemsHolder.getFallbackBlock() && value.hasCollision()) &&
199 (!value.isTransparent() || value == mGameItemsHolder.getBlock("glass") || value.isChest() || value.isSlab())) {
200 setBackMap(x, y, value);
201 return true;
203 return false;
206 private void playerDurateTool() {
207 final InventoryItem playerCurrentItem = mMobsController.getPlayer().inventory.getActiveItem();
208 if (playerCurrentItem.getItem().isTool()) {
209 mMobsController.getPlayer().decreaseCurrentItemCount(mGameItemsHolder);
213 private boolean shouldDrop(Block block) {
214 final Item item = mMobsController.getPlayer().inventory.getActiveItem().getItem();
215 int toolLevel = item.isTool() ? ((Item.Tool) item).getLevel() : 0;
216 if (item.isTool() && block.getParams().getToolType() != item.getClass()) {
217 toolLevel = 0;
219 return toolLevel >= block.getParams().getToolLevel();
222 public void destroyForeMap(int x, int y) {
223 Block block = getForeMap(x, y);
224 if (block.isContainer()) {
225 mContainerController.destroyContainer(x, y, FOREGROUND_Z);
227 if (block.hasDrop() && shouldDrop(block)) {
228 for (int i = 0; i < block.getParams().getDropInfo().getCount(); i++) {
229 mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, mGameItemsHolder.getItem(block.getDrop()));
232 playerDurateTool();
233 placeToForeground(x, y, mGameItemsHolder.getFallbackBlock());
236 public WorldGeneratorConfig getWorldConfig() {
237 return mWorldConfig;
240 public void destroyBackMap(int x, int y) {
241 Block block = getBackMap(x, y);
242 if (block.hasDrop() && shouldDrop(block)) {
243 for (int i = 0; i < block.getParams().getDropInfo().getCount(); i++) {
244 mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, mGameItemsHolder.getItem(block.getDrop()));
247 playerDurateTool();
248 placeToBackground(x, y, mGameItemsHolder.getFallbackBlock());
251 @CheckForNull
252 private Container getContainerAt(int x, int y, int z) {
253 return mContainerController.getContainer(transformX(x), y, z);
256 @CheckForNull
257 public Container getForegroundContainer(int x, int y) {
258 return getContainerAt(x, y, FOREGROUND_Z);
261 @CheckForNull
262 public Container getBackgroundContainer(int x, int y) {
263 return getContainerAt(x, y, BACKGROUND_Z);
266 @CheckForNull
267 public Furnace getForegroundFurnace(int x, int y) {
268 @CheckForNull
269 final Container container = getForegroundContainer(x, y);
271 if (container instanceof Furnace) {
272 return (Furnace) container;
275 return null;
278 @CheckForNull
279 public Furnace getBackgroundFurnace(int x, int y) {
280 @CheckForNull
281 final Container container = getBackgroundContainer(x, y);
283 if (container instanceof Furnace) {
284 return (Furnace) container;
287 return null;