From f34df6e5eb1052467333f1461c67e75b21eb0d95 Mon Sep 17 00:00:00 2001 From: fredboy Date: Wed, 24 Apr 2024 04:00:38 +0700 Subject: [PATCH] Prettier world + ores --- android/assets/json/game_items.json | 67 +++++++-- .../assets/textures/blocks/grass_snowed.png | Bin 0 -> 414 bytes .../assets/textures/blocks/leaves_birch.png | Bin 375 -> 0 bytes android/assets/textures/blocks/leaves_oak.png | Bin 376 -> 697 bytes .../assets/textures/blocks/leaves_spruce.png | Bin 374 -> 0 bytes .../game/actions/UpdateBlockActionsModule.kt | 8 + .../game/actions/UseItemActionsModule.kt | 8 + .../updateblock/UpdateSnowedGrassAction.kt | 24 +++ .../actions/useitem/UseEmptyBucketAction.kt | 37 +++++ .../actions/useitem/UseLavaBucketAction.kt | 5 +- .../actions/useitem/UseWaterBucketAction.kt | 4 +- .../game/debug/DebugInfoStringsProvider.kt | 2 +- ...tCreativeInventoryItemMouseInputHandler.kt | 2 +- .../cavedroid/game/mobs/Player.java | 37 ++++- .../cavedroid/game/model/block/Block.kt | 11 +- .../game/model/block/CommonBlockParams.kt | 1 + .../cavedroid/game/model/dto/BlockDto.kt | 1 + .../game/model/item/InventoryItem.kt | 3 +- .../game/model/mapper/BlockMapper.kt | 1 + .../cavedroid/game/model/world/Biome.kt | 3 +- .../world/generator/WorldGeneratorConfig.kt | 15 +- .../cavedroid/game/render/DropsRenderer.kt | 3 +- .../render/windows/AbstractWindowRenderer.kt | 3 +- .../cavedroid/game/world/GameWorld.java | 13 +- .../game/world/GameWorldGenerator.kt | 141 +++++++++++++++++- .../cavedroid/misc/utils/RenderingUtils.kt | 6 + .../cavedroid/misc/utils/SpriteUtils.kt | 10 +- 27 files changed, 353 insertions(+), 52 deletions(-) create mode 100644 android/assets/textures/blocks/grass_snowed.png delete mode 100644 android/assets/textures/blocks/leaves_birch.png delete mode 100644 android/assets/textures/blocks/leaves_spruce.png create mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSnowedGrassAction.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseEmptyBucketAction.kt diff --git a/android/assets/json/game_items.json b/android/assets/json/game_items.json index be44454..6db0467 100644 --- a/android/assets/json/game_items.json +++ b/android/assets/json/game_items.json @@ -21,6 +21,13 @@ "tool_level": 0, "tool_type": "shovel" }, + "grass_snowed": { + "hp": 54, + "drop": "dirt", + "texture": "grass_snowed", + "tool_level": 0, + "tool_type": "shovel" + }, "dirt": { "hp": 45, "drop": "dirt", @@ -48,7 +55,7 @@ "block_required": true, "drop": "sapling_oak", "texture": "sapling_oak", - "hp": 1 + "hp": 0 }, "bedrock": { "drop": "bedrock", @@ -109,6 +116,20 @@ "tool_level": 1, "tool_type": "pickaxe" }, + "diamond_ore": { + "hp": 900, + "drop": "diamond", + "texture": "diamond_ore", + "tool_level": 3, + "tool_type": "pickaxe" + }, + "diamond_block": { + "hp": 1500, + "drop": "diamond_block", + "texture": "diamond_block", + "tool_level": 3, + "tool_type": "pickaxe" + }, "log_oak": { "hp": 180, "drop": "log_oak", @@ -118,11 +139,11 @@ }, "leaves_oak": { "hp": 21, - "transparent": true, "drop": "leaves_oak", "texture": "leaves_oak", "tool_level": 1, - "tool_type": "shears" + "tool_type": "shears", + "tint": "#5AC557" }, "sponge": { "hp": 54, @@ -201,7 +222,9 @@ "drop": "tallgrass", "texture": "tallgrass", "tool_level": 1, - "tool_type": "shears" + "tool_type": "shears", + "tint": "#5AC557", + "hp": 0 }, "deadbush": { "collision": false, @@ -210,7 +233,8 @@ "drop": "deadbush", "texture": "deadbush", "tool_level": 1, - "tool_type": "shears" + "tool_type": "shears", + "hp": 0 }, "bricks": { "hp": 600, @@ -224,28 +248,32 @@ "transparent": true, "block_required": true, "drop": "dandelion", - "texture": "dandelion" + "texture": "dandelion", + "hp": 0 }, "rose": { "collision": false, "transparent": true, "block_required": true, "drop": "rose", - "texture": "rose" + "texture": "rose", + "hp": 0 }, "mushroom_brown": { "collision": false, "transparent": true, "block_required": true, "drop": "mushroom_brown", - "texture": "mushroom_brown" + "texture": "mushroom_brown", + "hp": 0 }, "mushroom_red": { "collision": false, "transparent": true, "block_required": true, "drop": "mushroom_red", - "texture": "mushroom_red" + "texture": "mushroom_red", + "hp": 0 }, "wool_colored_white": { "hp": 75, @@ -650,7 +678,7 @@ "damage": 4 }, "obsidian": { - "hp": 1500, + "hp": 15000, "drop": "obsidian", "texture": "obsidian", "tool_level": 4, @@ -733,6 +761,11 @@ "type": "block", "texture": "coal_ore" }, + "diamond_ore": { + "name": "Diamond Ore", + "type": "block", + "texture": "diamond_ore" + }, "log_oak": { "name": "Wood", "type": "block", @@ -899,6 +932,11 @@ "type": "block", "texture": "iron_block" }, + "diamond_block": { + "name": "Diamond Block", + "type": "block", + "texture": "diamond_block" + }, "stone_slab": { "name": "Stone Slab", "type": "slab", @@ -1132,21 +1170,24 @@ "type": "bucket", "texture": "bucket_empty", "origin_x": 0.25, - "action_key": "use_empty_bucket" + "action_key": "use_empty_bucket", + "max_stack": 1 }, "bucket_water": { "name": "Water Bucket", "type": "bucket", "texture": "bucket_water", "origin_x": 0.25, - "action_key": "use_water_bucket" + "action_key": "use_water_bucket", + "max_stack": 1 }, "bucket_lava": { "name": "Lava Bucket", "type": "bucket", "texture": "bucket_lava", "origin_x": 0.25, - "action_key": "use_lava_bucket" + "action_key": "use_lava_bucket", + "max_stack": 1 } } } diff --git a/android/assets/textures/blocks/grass_snowed.png b/android/assets/textures/blocks/grass_snowed.png new file mode 100644 index 0000000000000000000000000000000000000000..730996da4f31bbde1f077a45ff9ba9755bbfcbb5 GIT binary patch literal 414 zcmV;P0b%}$P)N2bPDNB8 zb~7$DE-^7j^FlWO00A0FL_t(IPhF2cOM+1p#?OanX>E5D5~QV}f)?LNP#gk55OOpK z8pO%LxfX}^rapn-CunraC1~+8_`Ce#a0#CG@|@?-dGC$=;Rk&G9zpWm*S;Q;qyH7^ zgk#NhCGq~b1r8d7w9zl_TdiStz4-ue5SO!CfXbjDRKWG3Z|1CXj#vsvfLVi(1RGHo z(G|frxa(R#s+-AeDhBDNhu(bDOqv_Go;S$?CzfK6UOf)L>+_h?ntjUfQ~)Goqy-(* zz(oe!xSS3HgE{|WT3eV-rM$rzPy=3oWhfADl}ag?$fpa-D8dd1dd`q~S)TT_KzRfB zXF~v?-c{TG!lvI6;>1s;*b z3=DjGL736~_k^`TL5ULAh?3y^w370~qEv>0#LT=By}Z;C1rt33J=4@yqg0@pubwWB zAr}6vlUDOG1q!%cPtas&KcHj~A*9mOuvp;N0)|;P^j>70lq`zNJEo9Vwl6&`u54HS zH*M4T>rVf!i2Sngvikk(WhHUH91#84Jt}G%l}?J z;vzNU#^gi4OWH3+Gc4O_q%<>K;rwOxAcm6;9tOQEXOGypHXIiC_>ry2BO>RFRI<|s z?g{w~y)9X<%dc|o)H=m>{j9z5=dT^MGZsl!Jo~vTlQDqJ+9j3mMa?d~`1|d--@HDY RS^x|H22WQ%mvv4FO#o~blI8#a diff --git a/android/assets/textures/blocks/leaves_oak.png b/android/assets/textures/blocks/leaves_oak.png index c2a54ee5e827094223e85d93d5bb957793f79a8e..d9027521b78eaa34aac1ff2d3e3c46f98617c7c2 100644 GIT binary patch delta 672 zcmV;R0$=_30=Wf{C4X~5NmK|32nc)#WQYI&0&q!0K~y-6eUi^=6Hye#e=~++pt<+V zBB0hbL=-a9g(z5@2)a_5K7m9ZrVFbDUqHd779T(|t`sUwz>2n%WZZStQYa>KCzZA_ z%(xgbSOw4K!abbx{W+f%ynCPWM}6D=N-Jm~A^=#H1wfgee0+>Jf+{JL zQXC#0QZAP>2@{$oHtg^3=RQp8?-OdJ84Lz&Y;0r;Cc|23y4@~r&CSl{2)^&<3nn!l zkEz$|h!&Jq*y0G4N`-bOOW5SC&RwB8cO~=0b?J7yBuT>O&ChvaV-sf*f*@ew)&jO| z1CS&MZ-3st=F!8)sFGrMG^Fm=X?NPx{W{`E&gh(N+sh(Czu#wSYKqaX5u?$Fot+&n zUb?{gr*+EZGN-4fT)TP=fRmFG&KJ*T9{9I?0K)Gfs-&=O8xtFv&E^^Xl}ZJGPNxIF z?(QzlW;2t}3R?N6@B37%)jaGf4#GeT1Znaj zl!gWgDToG%2jm+_RMhl5IAks!#{r7f+3WS%zFmJBx{AwvoPWT1yiMP=fAutwpm=;e zve^bePR$rJgDU9vhXo-P))@rs*%;Kx8nnhRv>8}iPM8Hwss?W3fI9v9einleD!lvI6;>1s;*b z3=Dh+K$tP>S|=w^P@=>&q9iy!t)x7$D3zfgF*C13FE6!3!9>qM&os5wC>5yYi>HfY zh=qUdq}{wsh5{~gW9+A2ILO+P(qYyyq3?xK(_(fP2hlHSUvzA=byzA|h*tc+$Jla+_ zG2@XZ}iS#MH%KQSQb#KQ`A z))(%Ku6vU{vrVcBFYGjCInmwlWM0bKxldg_DmCb?l@$GOV8!-#(f=6dn5>&>mk?$Q P^gn~AtDnm{r-UW|$9;@p diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/UpdateBlockActionsModule.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/UpdateBlockActionsModule.kt index be84127..5dcfe0e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/UpdateBlockActionsModule.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/UpdateBlockActionsModule.kt @@ -41,4 +41,12 @@ class UpdateBlockActionsModule { fun bindUpdateGrassAction(action: UpdateGrassAction): IUpdateBlockAction { return action; } + + @Binds + @IntoMap + @StringKey(UpdateSnowedGrassAction.BLOCK_KEY) + @GameScope + fun bindUpdateSnowedGrassAction(action: UpdateSnowedGrassAction): IUpdateBlockAction { + return action; + } } \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt index aeb64f0..0206d5f 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt @@ -26,4 +26,12 @@ class UseItemActionsModule { return action } + @Binds + @IntoMap + @StringKey(UseEmptyBucketAction.ACTION_KEY) + @GameScope + fun bindUseEmptyBucketAction(action: UseEmptyBucketAction): IUseItemAction { + return action + } + } diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSnowedGrassAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSnowedGrassAction.kt new file mode 100644 index 0000000..8b7f0e3 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSnowedGrassAction.kt @@ -0,0 +1,24 @@ +package ru.deadsoftware.cavedroid.game.actions.updateblock + +import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.world.GameWorld +import javax.inject.Inject + +@GameScope +class UpdateSnowedGrassAction @Inject constructor( + private val gameWorld: GameWorld, + private val mGameItemsHolder: GameItemsHolder, +) : IUpdateBlockAction { + + override fun update(x: Int, y: Int) { + val blockOnTop = gameWorld.getForeMap(x, y - 1) + if (blockOnTop.collision || blockOnTop.isFluid()) { + gameWorld.setForeMap(x, y, mGameItemsHolder.getBlock("dirt")) + } + } + + companion object { + const val BLOCK_KEY = "grass_snowed" + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseEmptyBucketAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseEmptyBucketAction.kt new file mode 100644 index 0000000..9f7c9f4 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseEmptyBucketAction.kt @@ -0,0 +1,37 @@ +package ru.deadsoftware.cavedroid.game.actions.useitem + +import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.model.block.Block +import ru.deadsoftware.cavedroid.game.model.item.Item +import ru.deadsoftware.cavedroid.game.world.GameWorld +import javax.inject.Inject + +@GameScope +class UseEmptyBucketAction @Inject constructor( + private val gameWorld: GameWorld, + private val mobsController: MobsController, + private val gameItemsHolder: GameItemsHolder, +) : IUseItemAction { + + override fun perform(item: Item.Usable, x: Int, y: Int) { + val foregroundBlock = gameWorld.getForeMap(x, y) + if (!foregroundBlock.isFluid()) { + return + } + gameWorld.resetForeMap(x, y) + + val filled = when (foregroundBlock) { + is Block.Lava -> gameItemsHolder.getItem("bucket_lava") + is Block.Water -> gameItemsHolder.getItem("bucket_water") + else -> throw IllegalStateException("unknown fluid") + } + + mobsController.player.setCurrentInventorySlotItem(filled) + } + + companion object { + const val ACTION_KEY = "use_empty_bucket" + } +} diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseLavaBucketAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseLavaBucketAction.kt index 7f834ae..9659617 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseLavaBucketAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseLavaBucketAction.kt @@ -16,7 +16,10 @@ class UseLavaBucketAction @Inject constructor( override fun perform(item: Item.Usable, x: Int, y: Int) { gameWorld.placeToForeground(x, y, gameItemsHolder.getBlock("lava")) - mobsController.player.setCurrentInventorySlotItem(gameItemsHolder.getItem("bucket_empty")) + + if (mobsController.player.gameMode != 1) { + mobsController.player.setCurrentInventorySlotItem(gameItemsHolder.getItem("bucket_empty")) + } } companion object { diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseWaterBucketAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseWaterBucketAction.kt index 596d587..15e08fc 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseWaterBucketAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseWaterBucketAction.kt @@ -16,7 +16,9 @@ class UseWaterBucketAction @Inject constructor( override fun perform(item: Item.Usable, x: Int, y: Int) { gameWorld.placeToForeground(x, y, gameItemsHolder.getBlock("water")) - mobsController.player.setCurrentInventorySlotItem(gameItemsHolder.getItem("bucket_empty")) + if (mobsController.player.gameMode != 1) { + mobsController.player.setCurrentInventorySlotItem(gameItemsHolder.getItem("bucket_empty")) + } } companion object { diff --git a/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt b/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt index 3a0ef06..c8147d1 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt @@ -20,7 +20,7 @@ class DebugInfoStringsProvider @Inject constructor( return listOf( "FPS: ${Gdx.graphics.framesPerSecond}", "X: ${player.mapX}", - "Y: ${player.upperMapY}", + "Y: ${gameWorld.height - player.upperMapY}", "CurX: ${player.cursorX}", "CurY: ${player.cursorY}", "Velocity: ${player.velocity}", diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt index 5e64027..ddd71c4 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt @@ -50,7 +50,7 @@ class SelectCreativeInventoryItemMouseInputHandler @Inject constructor( destination = mobsController.player.inventory, destinationOffset = 1, startIndex = 0, - endIndex = mobsController.player.inventory.size - 2 + endIndex = mobsController.player.inventory.size - 1 ) val item = gameItemsHolder.getItemFromCreativeInventory(itemIndex) diff --git a/core/src/ru/deadsoftware/cavedroid/game/mobs/Player.java b/core/src/ru/deadsoftware/cavedroid/game/mobs/Player.java index 83f3257..b369f1c 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/mobs/Player.java +++ b/core/src/ru/deadsoftware/cavedroid/game/mobs/Player.java @@ -36,6 +36,9 @@ public class Player extends Mob { public int cursorX = 0; public int cursorY = 0; + @CheckForNull + private Vector2 spawnPoint = null; + public ControlMode controlMode = ControlMode.WALK; public enum ControlMode { @@ -107,18 +110,30 @@ public class Player extends Mob { } private Vector2 getSpawnPoint(GameWorld gameWorld, GameItemsHolder itemsHolder) { - int y; - for (y = 0; y < gameWorld.getHeight(); y++) { - if (y == gameWorld.getHeight() - 1) { - y = 60; - gameWorld.setForeMap(0, y, itemsHolder.getBlock("grass")); + if (spawnPoint != null) { + return spawnPoint; + } + + int y, x = gameWorld.getWidth() / 2; + for (y = 0; y <= gameWorld.getWorldConfig().getSeaLevel(); y++) { + if (y == gameWorld.getWorldConfig().getSeaLevel()) { + for (x = 0; x < gameWorld.getWidth(); x++) { + if (gameWorld.getForeMap(x, y).getParams().getHasCollision()) { + break; + } + if (x == gameWorld.getWidth() - 1) { + gameWorld.setForeMap(x, y, itemsHolder.getBlock("grass")); + break; + } + } break; } - if (gameWorld.hasForeAt(0, y) && gameWorld.getForeMap(0, y).hasCollision()) { + if (gameWorld.hasForeAt(x, y) && gameWorld.getForeMap(x, y).hasCollision()) { break; } } - return new Vector2(8 - getWidth() / 2, (float) y * 16 - getHeight()); + spawnPoint = new Vector2(x * 16 + 8 - getWidth() / 2, (float) y * 16 - getHeight()); + return spawnPoint; } public void setDir(Direction dir) { @@ -247,6 +262,9 @@ public class Player extends Mob { final Sprite sprite = item.getSprite(); final boolean smallSprite = !item.isTool() || item.isShears(); + final float originalWidth = sprite.getWidth(); + final float originalHeight = sprite.getHeight(); + if (smallSprite) { sprite.setSize(Drop.DROP_SIZE, Drop.DROP_SIZE); } @@ -275,12 +293,15 @@ public class Player extends Mob { SpriteUtilsKt.applyOrigin(sprite, spriteOrigin); } - SpriteUtilsKt.drawSprite(spriteBatch, sprite, itemX, itemY, -handMultiplier * rotate); + sprite.setRotation(-handMultiplier * rotate); + sprite.setPosition(itemX, itemY); + sprite.draw(spriteBatch); // dont forget to reset sprite.setFlip(false, sprite.isFlipY()); sprite.setRotation(0); sprite.setOriginCenter(); + sprite.setSize(originalWidth, originalHeight); if (item.isTool()) { sprite.rotate90(looksRight()); } diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/block/Block.kt b/core/src/ru/deadsoftware/cavedroid/game/model/block/Block.kt index 9669a53..76c6ac5 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/block/Block.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/block/Block.kt @@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.math.Rectangle import com.badlogic.gdx.utils.TimeUtils import ru.deadsoftware.cavedroid.game.model.item.Item +import ru.deadsoftware.cavedroid.misc.utils.colorFromHexString import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract @@ -56,7 +57,10 @@ sealed class Block { val width = 16 - params.spriteMargins.left - params.spriteMargins.right val height = 16 - params.spriteMargins.top - params.spriteMargins.bottom Sprite(params.texture, params.spriteMargins.left, 16 * y + params.spriteMargins.top, width, height) - .apply { flip(false, true) } + .apply { + flip(false, true) + params.tint?.let { tint -> color = colorFromHexString(tint) } + } } } } @@ -66,7 +70,10 @@ sealed class Block { val width = 16 - params.spriteMargins.left - params.spriteMargins.right val height = 16 - params.spriteMargins.top - params.spriteMargins.bottom Sprite(tex, params.spriteMargins.left, params.spriteMargins.top, width, height) - .apply { flip(false, true) } + .apply { + flip(false, true) + params.tint?.let { tint -> color = colorFromHexString(tint) } + } } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/block/CommonBlockParams.kt b/core/src/ru/deadsoftware/cavedroid/game/model/block/CommonBlockParams.kt index 202b191..e98f1be 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/block/CommonBlockParams.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/block/CommonBlockParams.kt @@ -19,4 +19,5 @@ data class CommonBlockParams( val toolLevel: Int, val toolType: Class?, val damage: Int, + val tint: String?, ) diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/dto/BlockDto.kt b/core/src/ru/deadsoftware/cavedroid/game/model/dto/BlockDto.kt index b8c6326..c6065b7 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/dto/BlockDto.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/dto/BlockDto.kt @@ -31,4 +31,5 @@ data class BlockDto( @SerialName("tool_level") val toolLevel: Int = 0, @SerialName("tool_type") val toolType: String? = null, @SerialName("damage") val damage: Int = 0, + @SerialName("tint") val tint: String? = null, ) diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/item/InventoryItem.kt b/core/src/ru/deadsoftware/cavedroid/game/model/item/InventoryItem.kt index 8918659..6cb2a9d 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/item/InventoryItem.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/item/InventoryItem.kt @@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.ShapeRenderer import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.misc.Assets +import ru.deadsoftware.cavedroid.misc.utils.drawSprite import ru.deadsoftware.cavedroid.misc.utils.drawString import ru.deadsoftware.cavedroid.misc.utils.px import java.io.Serializable @@ -54,7 +55,7 @@ class InventoryItem @JvmOverloads constructor( } val sprite = item.sprite - spriteBatch.draw(sprite, x, y) + spriteBatch.drawSprite(sprite, x, y) if (amount < 2) { return diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/mapper/BlockMapper.kt b/core/src/ru/deadsoftware/cavedroid/game/model/mapper/BlockMapper.kt index e97659a..85d8cb7 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/mapper/BlockMapper.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/mapper/BlockMapper.kt @@ -55,6 +55,7 @@ class BlockMapper @Inject constructor( toolLevel = dto.toolLevel, toolType = mapToolType(dto), damage = dto.damage, + tint = dto.tint, ) } diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/world/Biome.kt b/core/src/ru/deadsoftware/cavedroid/game/model/world/Biome.kt index e2d3d7d..ee214bd 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/world/Biome.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/world/Biome.kt @@ -2,5 +2,6 @@ package ru.deadsoftware.cavedroid.game.model.world enum class Biome { PLAINS, - DESERT + DESERT, + WINTER } \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/world/generator/WorldGeneratorConfig.kt b/core/src/ru/deadsoftware/cavedroid/game/model/world/generator/WorldGeneratorConfig.kt index 19a7c2d..64da3fe 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/world/generator/WorldGeneratorConfig.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/world/generator/WorldGeneratorConfig.kt @@ -15,20 +15,17 @@ data class WorldGeneratorConfig( ) { companion object { - private const val DEFAULT_WIDTH = 1024 - private const val DEFAULT_HEIGHT = 256 - private const val DEFAULT_MIN_BIOME_SIZE = 64 fun getDefault(): WorldGeneratorConfig { return WorldGeneratorConfig( - width = DEFAULT_WIDTH, - height = DEFAULT_HEIGHT, + width = 1024, + height = 256, seed = TimeUtils.millis(), - minSurfaceHeight = DEFAULT_HEIGHT / 4, - maxSurfaceHeight = DEFAULT_HEIGHT * 3 / 4, + maxSurfaceHeight = 208, + minSurfaceHeight = 128, biomes = Biome.entries.toList(), - minBiomeSize = DEFAULT_MIN_BIOME_SIZE, - seaLevel = DEFAULT_HEIGHT / 2, + minBiomeSize = 64, + seaLevel = 192, ) } diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt index efc7aa1..a17bd61 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt @@ -22,11 +22,12 @@ class DropsRenderer @Inject constructor( override fun draw(spriteBatch: SpriteBatch, shapeRenderer: ShapeRenderer, viewport: Rectangle, delta: Float) { dropController.forEach { drop -> drop.cycledInsideWorld(viewport, gameWorld.width.px)?.let { dropRect -> - drop.item.sprite.setSize(dropRect.width, dropRect.height) spriteBatch.drawSprite( sprite = drop.item.sprite, x = dropRect.x - viewport.x, y = dropRect.y - viewport.y, + width = dropRect.width, + height = dropRect.height, ) } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/windows/AbstractWindowRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/windows/AbstractWindowRenderer.kt index 52935fe..57cf81b 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/windows/AbstractWindowRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/windows/AbstractWindowRenderer.kt @@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.ShapeRenderer import ru.deadsoftware.cavedroid.game.model.item.InventoryItem import ru.deadsoftware.cavedroid.game.model.item.Item +import ru.deadsoftware.cavedroid.misc.utils.drawSprite abstract class AbstractWindowRenderer { @@ -39,7 +40,7 @@ abstract class AbstractWindowRenderer { val itemY = gridY + (index / itemsInRow) * cellHeight inventoryItem?.draw(spriteBatch, shapeRenderer, itemX, itemY) - ?: item?.let { spriteBatch.draw(it.sprite, itemX, itemY) } + ?: item?.let { spriteBatch.drawSprite(it.sprite, itemX, itemY) } } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/world/GameWorld.java b/core/src/ru/deadsoftware/cavedroid/game/world/GameWorld.java index f8a5cc9..f2fd27d 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/world/GameWorld.java +++ b/core/src/ru/deadsoftware/cavedroid/game/world/GameWorld.java @@ -26,6 +26,8 @@ public class GameWorld { private final Block[][] mForeMap; private final Block[][] mBackMap; + private final WorldGeneratorConfig mWorldConfig = WorldGeneratorConfig.Companion.getDefault(); + @Inject public GameWorld(DropController dropController, MobsController mobsController, @@ -39,10 +41,9 @@ public class GameWorld { boolean isNewGame = foreMap == null || backMap == null; if (isNewGame) { - final WorldGeneratorConfig config = WorldGeneratorConfig.Companion.getDefault(); - mWidth = config.getWidth(); - mHeight = config.getHeight(); - Pair maps = new GameWorldGenerator(config, mGameItemsHolder).generate(); + mWidth = mWorldConfig.getWidth(); + mHeight = mWorldConfig.getHeight(); + Pair maps = new GameWorldGenerator(mWorldConfig, mGameItemsHolder).generate(); mForeMap = maps.getFirst(); mBackMap = maps.getSecond(); mMobsController.getPlayer().respawn(this, mGameItemsHolder); @@ -200,7 +201,9 @@ public class GameWorld { placeToForeground(x, y, mGameItemsHolder.getFallbackBlock()); } - + public WorldGeneratorConfig getWorldConfig() { + return mWorldConfig; + } public void destroyBackMap(int x, int y) { Block block = getBackMap(x, y); diff --git a/core/src/ru/deadsoftware/cavedroid/game/world/GameWorldGenerator.kt b/core/src/ru/deadsoftware/cavedroid/game/world/GameWorldGenerator.kt index b984c4d..e00a0ea 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/world/GameWorldGenerator.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/world/GameWorldGenerator.kt @@ -1,5 +1,6 @@ package ru.deadsoftware.cavedroid.game.world +import com.google.common.primitives.Ints.min import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.model.block.Block import ru.deadsoftware.cavedroid.game.model.world.Biome @@ -21,11 +22,14 @@ class GameWorldGenerator( private val heights by lazy { generateHeights() } private val biomesMap by lazy { generateBiomes() } + private val plainsPlants = listOf("dandelion", "rose", "tallgrass") + private val mushrooms = listOf("mushroom_brown", "mushroom_red",) + private fun generateHeights(): IntArray { val surfaceHeightRange = config.minSurfaceHeight .. config.maxSurfaceHeight val result = IntArray(config.width) - result[0] = (config.minSurfaceHeight + config.maxSurfaceHeight) / 2 + result[0] = surfaceHeightRange.random(random) for (x in 1 ..< config.width) { val previous = result[x - 1] @@ -59,6 +63,35 @@ class GameWorldGenerator( return xSequence.associateWith { config.biomes.random(random) } } + private fun winterBiome(x: Int) { + assert(x in 0 ..< config.width) { "x not in range of world width" } + + val surfaceHeight = heights[x] + + val grass = gameItemsHolder.getBlock("grass_snowed") + val bedrock = gameItemsHolder.getBlock("bedrock") + val dirt = gameItemsHolder.getBlock("dirt") + val stone = gameItemsHolder.getBlock("stone") + + foreMap[x][surfaceHeight] = grass + foreMap[x][config.height - 1] = bedrock + backMap[x][surfaceHeight] = grass + backMap[x][config.height - 1] = bedrock + + for (y in min(surfaceHeight + 1, config.seaLevel) ..< config.height - 1) { + if (y <= surfaceHeight) { + backMap[x][y] = dirt + continue + } + + foreMap[x][y] = when { + y < surfaceHeight + random.nextInt(5, 8) -> dirt + else -> stone + } + backMap[x][y] = foreMap[x][y] + } + } + private fun plainsBiome(x: Int) { assert(x in 0 ..< config.width) { "x not in range of world width" } @@ -74,13 +107,27 @@ class GameWorldGenerator( backMap[x][surfaceHeight] = grass backMap[x][config.height - 1] = bedrock - for (y in surfaceHeight + 1 ..< config.height - 1) { + for (y in min(surfaceHeight + 1, config.seaLevel) ..< config.height - 1) { + if (y <= surfaceHeight) { + backMap[x][y] = dirt + continue + } + foreMap[x][y] = when { y < surfaceHeight + random.nextInt(5, 8) -> dirt else -> stone } backMap[x][y] = foreMap[x][y] } + + val plant = random.nextInt(100) + if (surfaceHeight < config.seaLevel) { + if (plant < 10) { + generateOak(x) + } else if (plant < 40) { + generateTallGrass(x) + } + } } private fun desertBiome(x: Int) { @@ -99,7 +146,12 @@ class GameWorldGenerator( backMap[x][surfaceHeight] = sand backMap[x][config.height - 1] = bedrock - for (y in surfaceHeight + 1 ..< config.height - 1) { + for (y in min(surfaceHeight + 1, config.seaLevel) ..< config.height - 1) { + if (y <= surfaceHeight) { + backMap[x][y] = sand + continue + } + foreMap[x][y] = when { y < surfaceHeight + random.nextInt(5, 8) -> sand y < surfaceHeight + random.nextInt(0, 2) -> sandstone @@ -108,8 +160,13 @@ class GameWorldGenerator( backMap[x][y] = foreMap[x][y] } - if (surfaceHeight < config.seaLevel && random.nextInt(100) < 5) { - generateCactus(x) + val plant = random.nextInt(100) + if (surfaceHeight < config.seaLevel) { + if (plant < 5) { + generateCactus(x) + } else if (plant < 10) { + generateDeadBush(x) + } } } @@ -137,6 +194,77 @@ class GameWorldGenerator( } } + private fun generateOak(x: Int) { + val log = gameItemsHolder.getBlock("log_oak") + val leaves = gameItemsHolder.getBlock("leaves_oak") + val h = heights[x] - 1 + val treeH = random.nextInt(5, 7) + val height = max(0, h - treeH) + + val top = height - 1 + if (top >= 0) { + foreMap[x][top] = leaves + backMap[x][top] = leaves + } + + for (x1 in max(0, x - 1) .. min(config.width - 1, x + 1)) { + for (y in height .. height + treeH - 4) { + foreMap[x1][y] = leaves + backMap[x1][y] = leaves + } + if (random.nextInt(15) < 3) { + foreMap[x1][heights[x1] - 1] = gameItemsHolder.getBlock(mushrooms.random(random)) + } + } + + for (y in h downTo height) { + backMap[x][y] = log + } + } + + private fun generateTallGrass(x: Int) { + val tallGrass = gameItemsHolder.getBlock(plainsPlants.random(random)) + val h = heights[x] - 1 + if (h > 0) { + foreMap[x][h] = tallGrass + } + } + + private fun generateDeadBush(x: Int) { + val bush = gameItemsHolder.getBlock("deadbush") + val h = heights[x] - 1 + if (h > 0) { + foreMap[x][h] = bush + } + } + + private fun generateOres(x : Int) { + val stone = gameItemsHolder.getBlock("stone") + val coal = gameItemsHolder.getBlock("coal_ore") + val iron = gameItemsHolder.getBlock("iron_ore") + val gold = gameItemsHolder.getBlock("gold_ore") + val diamond = gameItemsHolder.getBlock("diamond_ore") + val lapis = gameItemsHolder.getBlock("lapis_ore") + + for (y in heights[x] ..< config.height) { + val res = random.nextInt(10000) + + val h = config.height - y + val block = when { + res in 0..<25 && h < 16 -> diamond + res in 25 ..< 50 && h < 32 -> gold + res in 50 ..< 250 && h < 64 -> iron + res in 250 ..< 450 && h < 128 -> coal + res in 450 ..< (450 + (25 - (abs(h - 16) * (25 / 16)))) -> lapis + else -> null + } + + if (block != null && foreMap[x][y] == stone) { + foreMap[x][y] = block + } + } + } + /** * Generate world */ @@ -149,7 +277,10 @@ class GameWorldGenerator( when (biome) { Biome.PLAINS -> plainsBiome(x) Biome.DESERT -> desertBiome(x) + Biome.WINTER -> winterBiome(x) } + + generateOres(x) } fillWater() diff --git a/core/src/ru/deadsoftware/cavedroid/misc/utils/RenderingUtils.kt b/core/src/ru/deadsoftware/cavedroid/misc/utils/RenderingUtils.kt index d197229..24813ac 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/utils/RenderingUtils.kt +++ b/core/src/ru/deadsoftware/cavedroid/misc/utils/RenderingUtils.kt @@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.g2d.GlyphLayout import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.math.Rectangle import ru.deadsoftware.cavedroid.misc.Assets +import java.awt.Color as JavaColor private fun Rectangle.shifted(shift: Float) = Rectangle(x + shift, y, width, height) @@ -50,3 +51,8 @@ fun SpriteBatch.drawString(str: String, x: Float, y: Float, color: Color = Color Assets.minecraftFont.color = color return Assets.minecraftFont.draw(this, str, x, y) } + +fun colorFromHexString(hex: String): Color { + val rgba = (JavaColor.decode(hex).rgb shl 8) or (0xFF) + return Color(rgba) +} diff --git a/core/src/ru/deadsoftware/cavedroid/misc/utils/SpriteUtils.kt b/core/src/ru/deadsoftware/cavedroid/misc/utils/SpriteUtils.kt index fd186e5..7b75e38 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/utils/SpriteUtils.kt +++ b/core/src/ru/deadsoftware/cavedroid/misc/utils/SpriteUtils.kt @@ -11,11 +11,17 @@ fun SpriteBatch.drawSprite( sprite: Sprite, x: Float, y: Float, - rotation: Float = 0f + rotation: Float = 0f, + width: Float = sprite.regionWidth.toFloat(), + height: Float = sprite.regionHeight.toFloat(), ) { - sprite.rotation = rotation sprite.setPosition(x, y) + sprite.setSize(width, height) + sprite.rotation = rotation sprite.draw(this) + + sprite.setSize(sprite.regionWidth.toFloat(), sprite.regionHeight.toFloat()) + sprite.rotation = 0f } fun Sprite.applyOrigin(origin: SpriteOrigin) { -- 2.29.2