DEADSOFTWARE

Update version script
[cavedroid.git] / core / src / main / java / ru / deadsoftware / cavedroid / game / world / GameWorld.java
1 package ru.deadsoftware.cavedroid.game.world;
3 import com.badlogic.gdx.math.MathUtils;
4 import kotlin.Pair;
5 import org.jetbrains.annotations.Nullable;
6 import ru.deadsoftware.cavedroid.game.GameItemsHolder;
7 import ru.deadsoftware.cavedroid.game.GameScope;
8 import ru.deadsoftware.cavedroid.game.mobs.MobsController;
9 import ru.deadsoftware.cavedroid.game.mobs.Pig;
10 import ru.deadsoftware.cavedroid.game.model.block.Block;
11 import ru.deadsoftware.cavedroid.game.model.item.InventoryItem;
12 import ru.deadsoftware.cavedroid.game.model.item.Item;
13 import ru.deadsoftware.cavedroid.game.model.world.generator.WorldGeneratorConfig;
14 import ru.deadsoftware.cavedroid.game.objects.container.Container;
15 import ru.deadsoftware.cavedroid.game.objects.drop.DropController;
16 import ru.deadsoftware.cavedroid.game.objects.container.Furnace;
17 import ru.deadsoftware.cavedroid.game.objects.container.ContainerController;
18 import ru.deadsoftware.cavedroid.misc.utils.MeasureUnitsUtilsKt;
20 import javax.inject.Inject;
22 @GameScope
23 public class GameWorld {
25 private static final int FOREGROUND_Z = 0;
26 private static final int BACKGROUND_Z = 1;
28 private final DropController mDropController;
29 private final MobsController mMobsController;
30 private final GameItemsHolder mGameItemsHolder;
31 private final ContainerController mContainerController;
33 private final int mWidth;
34 private final int mHeight;
35 private final Block[][] mForeMap;
36 private final Block[][] mBackMap;
38 private final WorldGeneratorConfig mWorldConfig = WorldGeneratorConfig.Companion.getDefault();
40 @Inject
41 public GameWorld(DropController dropController,
42 MobsController mobsController,
43 GameItemsHolder gameItemsHolder,
44 ContainerController containerController,
45 @Nullable Block[][] foreMap,
46 @Nullable Block[][] backMap) {
47 mDropController = dropController;
48 mMobsController = mobsController;
49 mGameItemsHolder = gameItemsHolder;
50 mContainerController = containerController;
52 boolean isNewGame = foreMap == null || backMap == null;
54 if (isNewGame) {
55 mWidth = mWorldConfig.getWidth();
56 mHeight = mWorldConfig.getHeight();
57 Pair<Block[][], Block[][]> maps = new GameWorldGenerator(mWorldConfig, mGameItemsHolder).generate();
58 mForeMap = maps.getFirst();
59 mBackMap = maps.getSecond();
60 spawnInitialMobs();
61 mMobsController.getPlayer().respawn(this, mGameItemsHolder);
62 } else {
63 mForeMap = foreMap;
64 mBackMap = backMap;
65 mWidth = mForeMap.length;
66 mHeight = mForeMap[0].length;
67 }
68 }
70 public int getWidth() {
71 return mWidth;
72 }
74 public int getHeight() {
75 return mHeight;
76 }
78 /**
79 * @deprecated for kotlin use {@link MeasureUnitsUtilsKt#getPx } extension val
80 */
81 @Deprecated
82 public float getWidthPx() {
83 return MeasureUnitsUtilsKt.getPx(mWidth);
84 }
86 /**
87 * @deprecated for kotlin use {@link MeasureUnitsUtilsKt#getPx } extension val
88 */
89 @Deprecated
90 public float getHeightPx() {
91 return MeasureUnitsUtilsKt.getPx(mHeight);
92 }
94 public Block[][] getFullForeMap() {
95 return mForeMap;
96 }
98 public Block[][] getFullBackMap() {
99 return mBackMap;
102 private int transformX(int x) {
103 x = x % getWidth();
104 if (x < 0) {
105 x = getWidth() - Math.abs(x);
107 return x;
110 private Block getMap(int x, int y, int layer) {
111 Block map = mGameItemsHolder.getFallbackBlock();
113 if (y < 0 || y >= getHeight()) {
114 return map;
117 x = transformX(x);
119 if (x < 0 || x >= getWidth()) {
120 return map;
123 map = (layer == 0) ? mForeMap[x][y] : mBackMap[x][y];
125 return map;
128 private void setMap(int x, int y, int layer, Block value) {
129 if (y < 0 || y >= getHeight()) {
130 return;
133 x = transformX(x);
135 if (x < 0 || x >= getWidth()) {
136 return;
139 mContainerController.destroyContainer(x, y, layer, false);
141 if (value.isContainer()) {
142 mContainerController.addContainer(x, y, layer, (Class<? extends Block.Container>) value.getClass());
145 if (layer == 0) {
146 mForeMap[x][y] = value;
147 } else {
148 mBackMap[x][y] = value;
152 private boolean isSameSlab(Block slab1, Block slab2) {
153 if (!(slab1 instanceof Block.Slab) || !(slab2 instanceof Block.Slab)) {
154 return false;
157 return slab1.getParams().getKey().equals(((Block.Slab) slab2).getOtherPartBlockKey())
158 || slab1.getParams().getKey().equals(slab2.getParams().getKey());
161 public boolean hasForeAt(int x, int y) {
162 return getMap(x, y, FOREGROUND_Z) != mGameItemsHolder.getFallbackBlock();
165 public boolean hasBackAt(int x, int y) {
166 return getMap(x, y, BACKGROUND_Z) != mGameItemsHolder.getFallbackBlock();
169 public Block getForeMap(int x, int y) {
170 return getMap(x, y, FOREGROUND_Z);
173 public void setForeMap(int x, int y, Block block) {
174 setMap(x, y, FOREGROUND_Z, block);
177 public void resetForeMap(int x, int y) {
178 setForeMap(x, y, mGameItemsHolder.getFallbackBlock());
181 public Block getBackMap(int x, int y) {
182 return getMap(x, y, BACKGROUND_Z);
185 public void setBackMap(int x, int y, Block block) {
186 setMap(x, y, BACKGROUND_Z, block);
189 public boolean canPlaceToForeground(int x, int y, Block value) {
190 return !hasForeAt(x, y) || value == mGameItemsHolder.getFallbackBlock() || !getForeMap(x, y).hasCollision();
193 public boolean placeToForeground(int x, int y, Block value) {
194 if (canPlaceToForeground(x, y, value)) {
195 setForeMap(x, y, value);
196 return true;
197 } else if (value instanceof Block.Slab && isSameSlab(value, getForeMap(x, y))) {
198 setForeMap(x, y, mGameItemsHolder.getBlock(((Block.Slab) value).getFullBlockKey()));
199 return true;
201 return false;
204 public boolean placeToBackground(int x, int y, Block value) {
205 if (value == mGameItemsHolder.getFallbackBlock() || (getBackMap(x, y) == mGameItemsHolder.getFallbackBlock() && value.hasCollision()) &&
206 (!value.isTransparent() || value == mGameItemsHolder.getBlock("glass") || value.isChest() || value.isSlab())) {
207 setBackMap(x, y, value);
208 return true;
210 return false;
213 private void playerDurateTool() {
214 final InventoryItem playerCurrentItem = mMobsController.getPlayer().inventory.getActiveItem();
215 if (playerCurrentItem.getItem().isTool()) {
216 mMobsController.getPlayer().decreaseCurrentItemCount(mGameItemsHolder);
220 private boolean shouldDrop(Block block) {
221 final Item item = mMobsController.getPlayer().inventory.getActiveItem().getItem();
222 int toolLevel = item.isTool() ? ((Item.Tool) item).getLevel() : 0;
223 if (item.isTool() && block.getParams().getToolType() != item.getClass()) {
224 toolLevel = 0;
226 return toolLevel >= block.getParams().getToolLevel();
229 private void spawnInitialMobs() {
230 for (int x = 0; x < getWidth(); x++) {
231 int y = 0;
232 while (y < getWorldConfig().getSeaLevel()) {
233 if (getForeMap(x, y) == mGameItemsHolder.getBlock("grass")) {
234 if (MathUtils.randomBoolean(.125f)) {
235 mMobsController.addMob(new Pig(MeasureUnitsUtilsKt.getPx(x), MeasureUnitsUtilsKt.getPx(y)));
237 break;
239 y++;
244 public void destroyForeMap(int x, int y) {
245 Block block = getForeMap(x, y);
246 if (block.isContainer()) {
247 mContainerController.destroyContainer(x, y, FOREGROUND_Z, true);
249 if (block.hasDrop() && shouldDrop(block)) {
250 for (int i = 0; i < block.getParams().getDropInfo().getCount(); i++) {
251 mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, mGameItemsHolder.getItem(block.getDrop()));
254 playerDurateTool();
255 placeToForeground(x, y, mGameItemsHolder.getFallbackBlock());
258 public WorldGeneratorConfig getWorldConfig() {
259 return mWorldConfig;
262 public void destroyBackMap(int x, int y) {
263 Block block = getBackMap(x, y);
264 if (block.isContainer()) {
265 mContainerController.destroyContainer(x, y, BACKGROUND_Z, true);
267 if (block.hasDrop() && shouldDrop(block)) {
268 for (int i = 0; i < block.getParams().getDropInfo().getCount(); i++) {
269 mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, mGameItemsHolder.getItem(block.getDrop()));
272 playerDurateTool();
273 placeToBackground(x, y, mGameItemsHolder.getFallbackBlock());
276 @Nullable
277 private Container getContainerAt(int x, int y, int z) {
278 return mContainerController.getContainer(transformX(x), y, z);
281 @Nullable
282 public Container getForegroundContainer(int x, int y) {
283 return getContainerAt(x, y, FOREGROUND_Z);
286 @Nullable
287 public Container getBackgroundContainer(int x, int y) {
288 return getContainerAt(x, y, BACKGROUND_Z);
291 @Nullable
292 public Furnace getForegroundFurnace(int x, int y) {
293 @Nullable
294 final Container container = getForegroundContainer(x, y);
296 if (container instanceof Furnace) {
297 return (Furnace) container;
300 return null;
303 @Nullable
304 public Furnace getBackgroundFurnace(int x, int y) {
305 @Nullable
306 final Container container = getBackgroundContainer(x, y);
308 if (container instanceof Furnace) {
309 return (Furnace) container;
312 return null;