DEADSOFTWARE

Add bed
[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 canPlaceToForeground(int x, int y, Block value) {
187 return !hasForeAt(x, y) || value == mGameItemsHolder.getFallbackBlock() || !getForeMap(x, y).hasCollision();
190 public boolean placeToForeground(int x, int y, Block value) {
191 if (canPlaceToForeground(x, y, value)) {
192 setForeMap(x, y, value);
193 return true;
194 } else if (value instanceof Block.Slab && isSameSlab(value, getForeMap(x, y))) {
195 setForeMap(x, y, mGameItemsHolder.getBlock(((Block.Slab) value).getFullBlockKey()));
196 return true;
198 return false;
201 public boolean placeToBackground(int x, int y, Block value) {
202 if (value == mGameItemsHolder.getFallbackBlock() || (getBackMap(x, y) == mGameItemsHolder.getFallbackBlock() && value.hasCollision()) &&
203 (!value.isTransparent() || value == mGameItemsHolder.getBlock("glass") || value.isChest() || value.isSlab())) {
204 setBackMap(x, y, value);
205 return true;
207 return false;
210 private void playerDurateTool() {
211 final InventoryItem playerCurrentItem = mMobsController.getPlayer().inventory.getActiveItem();
212 if (playerCurrentItem.getItem().isTool()) {
213 mMobsController.getPlayer().decreaseCurrentItemCount(mGameItemsHolder);
217 private boolean shouldDrop(Block block) {
218 final Item item = mMobsController.getPlayer().inventory.getActiveItem().getItem();
219 int toolLevel = item.isTool() ? ((Item.Tool) item).getLevel() : 0;
220 if (item.isTool() && block.getParams().getToolType() != item.getClass()) {
221 toolLevel = 0;
223 return toolLevel >= block.getParams().getToolLevel();
226 public void destroyForeMap(int x, int y) {
227 Block block = getForeMap(x, y);
228 if (block.isContainer()) {
229 mContainerController.destroyContainer(x, y, FOREGROUND_Z);
231 if (block.hasDrop() && shouldDrop(block)) {
232 for (int i = 0; i < block.getParams().getDropInfo().getCount(); i++) {
233 mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, mGameItemsHolder.getItem(block.getDrop()));
236 playerDurateTool();
237 placeToForeground(x, y, mGameItemsHolder.getFallbackBlock());
240 public WorldGeneratorConfig getWorldConfig() {
241 return mWorldConfig;
244 public void destroyBackMap(int x, int y) {
245 Block block = getBackMap(x, y);
246 if (block.hasDrop() && shouldDrop(block)) {
247 for (int i = 0; i < block.getParams().getDropInfo().getCount(); i++) {
248 mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, mGameItemsHolder.getItem(block.getDrop()));
251 playerDurateTool();
252 placeToBackground(x, y, mGameItemsHolder.getFallbackBlock());
255 @CheckForNull
256 private Container getContainerAt(int x, int y, int z) {
257 return mContainerController.getContainer(transformX(x), y, z);
260 @CheckForNull
261 public Container getForegroundContainer(int x, int y) {
262 return getContainerAt(x, y, FOREGROUND_Z);
265 @CheckForNull
266 public Container getBackgroundContainer(int x, int y) {
267 return getContainerAt(x, y, BACKGROUND_Z);
270 @CheckForNull
271 public Furnace getForegroundFurnace(int x, int y) {
272 @CheckForNull
273 final Container container = getForegroundContainer(x, y);
275 if (container instanceof Furnace) {
276 return (Furnace) container;
279 return null;
282 @CheckForNull
283 public Furnace getBackgroundFurnace(int x, int y) {
284 @CheckForNull
285 final Container container = getBackgroundContainer(x, y);
287 if (container instanceof Furnace) {
288 return (Furnace) container;
291 return null;