From: fredboy Date: Fri, 10 May 2024 09:56:29 +0000 (+0700) Subject: Add furnace, more craft and items X-Git-Tag: alpha0.9.0~7 X-Git-Url: http://deadsoftware.ru/gitweb?a=commitdiff_plain;h=c447b95aeb883113ff1d53a3178828929c1eb92f;p=cavedroid.git Add furnace, more craft and items --- diff --git a/android/assets/chest.png b/android/assets/chest.png new file mode 100644 index 0000000..961891f Binary files /dev/null and b/android/assets/chest.png differ diff --git a/android/assets/furnace.png b/android/assets/furnace.png new file mode 100644 index 0000000..fc04793 Binary files /dev/null and b/android/assets/furnace.png differ diff --git a/android/assets/json/crafting.json b/android/assets/json/crafting.json index ddb9a67..837a977 100644 --- a/android/assets/json/crafting.json +++ b/android/assets/json/crafting.json @@ -43,11 +43,62 @@ "input": ["cobblestone", "none", "none", "stick", "none", "none", "stick", "none", "none"], "count": 131 }, + "iron_pickaxe": { + "input": ["iron_ingot", "iron_ingot", "iron_ingot", "none", "stick", "none", "none", "stick", "none"], + "count": 251 + }, + "iron_axe": { + "input": ["iron_ingot", "iron_ingot", "none", "iron_ingot", "stick", "none", "none", "stick", "none"], + "count": 250 + }, + "iron_sword": { + "input": ["iron_ingot", "none", "none", "iron_ingot", "none", "none", "stick", "none", "none"], + "count": 251 + }, + "iron_shovel": { + "input": ["iron_ingot", "none", "none", "stick", "none", "none", "stick", "none", "none"], + "count": 250 + }, + "gold_pickaxe": { + "input": ["gold_ingot", "gold_ingot", "gold_ingot", "none", "stick", "none", "none", "stick", "none"], + "count": 33 + }, + "gold_axe": { + "input": ["gold_ingot", "gold_ingot", "none", "gold_ingot", "stick", "none", "none", "stick", "none"], + "count": 32 + }, + "gold_sword": { + "input": ["gold_ingot", "none", "none", "gold_ingot", "none", "none", "stick", "none", "none"], + "count": 33 + }, + "gold_shovel": { + "input": ["gold_ingot", "none", "none", "stick", "none", "none", "stick", "none", "none"], + "count": 32 + }, + "diamond_pickaxe": { + "input": ["diamond", "diamond", "diamond", "none", "stick", "none", "none", "stick", "none"], + "count": 1562 + }, + "diamond_axe": { + "input": ["diamond", "diamond", "none", "diamond", "stick", "none", "none", "stick", "none"], + "count": 1561 + }, + "diamond_sword": { + "input": ["diamond", "none", "none", "diamond", "none", "none", "stick", "none", "none"], + "count": 1562 + }, + "diamond_shovel": { + "input": ["diamond", "none", "none", "stick", "none", "none", "stick", "none", "none"], + "count": 1561 + }, "snow_block": { "input": ["snowball", "snowball", "none", "snowball", "snowball", "none", "none", "none", "none"], "count": 1 }, "crafting_table": { "input": ["planks.*", "planks.*", "none", "planks.*", "planks.*", "none", "none", "none", "none"] + }, + "furnace": { + "input": ["cobblestone", "cobblestone", "cobblestone", "cobblestone", "none", "cobblestone", "cobblestone", "cobblestone", "cobblestone"] } } \ No newline at end of file diff --git a/android/assets/json/game_items.json b/android/assets/json/game_items.json index d8523b9..7749345 100644 --- a/android/assets/json/game_items.json +++ b/android/assets/json/game_items.json @@ -768,6 +768,18 @@ "hp": 60, "tool_level": 1, "tool_type": "shovel" + }, + "furnace": { + "hp": 1050, + "collision": true, + "transparent": false, + "drop": "furnace", + "texture": "furnace", + "animated": true, + "frames": 2, + "tool_level": 1, + "tool_type": "pickaxe", + "meta": "furnace" } }, "items": { @@ -794,32 +806,43 @@ "cobblestone": { "name": "Cobblestone", "type": "block", - "texture": "cobblestone" + "texture": "cobblestone", + "smelt_product": "stone" }, "planks_oak": { "name": "Oak Planks", "type": "block", - "texture": "planks_oak" + "texture": "planks_oak", + "burning_time": 15000 }, "sapling_oak": { "name": "Oak Sapling", "type": "block", - "texture": "sapling_oak" + "texture": "sapling_oak", + "burning_time": 5000 }, "planks_spruce": { "name": "Spruce Planks", "type": "block", - "texture": "planks_spruce" + "texture": "planks_spruce", + "burning_time": 15000 }, "crafting_table": { "name": "Crafting Table", "type": "block", - "texture": "crafting_table" + "texture": "crafting_table", + "burning_time": 15000 + }, + "furnace": { + "name": "Furnace", + "type": "block", + "texture": "furnace_off" }, "sapling_spruce": { "name": "Spruce Sapling", "type": "block", - "texture": "sapling_spruce" + "texture": "sapling_spruce", + "burning_time": 5000 }, "bedrock": { "name": "Bedrock", @@ -829,7 +852,8 @@ "sand": { "name": "Sand", "type": "block", - "texture": "sand" + "texture": "sand", + "smelt_product": "glass" }, "gravel": { "name": "Gravel", @@ -839,27 +863,33 @@ "gold_ore": { "name": "Golden Ore", "type": "block", - "texture": "gold_ore" + "texture": "gold_ore", + "smelt_product": "gold_ingot" }, "iron_ore": { "name": "Iron Ore", "type": "block", - "texture": "iron_ore" + "texture": "iron_ore", + "smelt_product": "iron_ingot" }, "coal_ore": { "name": "Coal Ore", "type": "block", - "texture": "coal_ore" + "texture": "coal_ore", + "smelt_product": "coal" }, "diamond_ore": { "name": "Diamond Ore", "type": "block", - "texture": "diamond_ore" + "texture": "diamond_ore", + "smelt_product": "diamond" }, "log_oak": { "name": "Wood", "type": "block", - "texture": "log_oak" + "texture": "log_oak", + "burning_time": 15000, + "smelt_product": "charcoal" }, "leaves_oak": { "name": "Leaves", @@ -869,7 +899,9 @@ "log_spruce": { "name": "Spruce", "type": "block", - "texture": "log_spruce" + "texture": "log_spruce", + "burning_time": 15000, + "smelt_product": "charcoal" }, "leaves_spruce": { "name": "Spruce Leaves", @@ -884,7 +916,8 @@ "lapis_ore": { "name": "Lapis Ore", "type": "block", - "texture": "lapis_ore" + "texture": "lapis_ore", + "smelt_product": "lapis_lazuli" }, "lapis_block": { "name": "Lapis Block", @@ -911,7 +944,8 @@ "name": "Dead Bush", "type": "block", "texture": "deadbush", - "origin_x": 0.5 + "origin_x": 0.5, + "burning_time": 5000 }, "bricks": { "name": "Bricks", @@ -1056,14 +1090,16 @@ "type": "slab", "texture": "oak_slab", "top_slab_block": "oak_slab_top", - "bottom_slab_block": "oak_slab_bottom" + "bottom_slab_block": "oak_slab_bottom", + "burn_time": 7500 }, "spruce_slab": { "name": "Spruce Slab", "type": "slab", "texture": "spruce_slab", "top_slab_block": "spruce_slab_top", - "bottom_slab_block": "spruce_slab_bottom" + "bottom_slab_block": "spruce_slab_bottom", + "burn_time": 7500 }, "cobblestone_slab": { "name": "Cobblestone Slab", @@ -1108,7 +1144,8 @@ }, "stick": { "name": "Stick", - "texture": "stick" + "texture": "stick", + "burning_time": 5000 }, "wood_sword": { "name": "Wooden Sword", @@ -1116,7 +1153,8 @@ "texture": "wood_sword", "origin_x": 0.125, "tool_level": 1, - "max_stack": 60 + "max_stack": 60, + "burning_time": 10000 }, "stone_sword": { "name": "Stone Sword", @@ -1197,7 +1235,8 @@ "texture": "wood_pickaxe", "origin_x": 0.125, "tool_level" : 1, - "max_stack": 59 + "max_stack": 59, + "burning_time": 10000 }, "stone_pickaxe": { "name": "Stone Pickaxe", @@ -1238,7 +1277,8 @@ "texture": "wood_axe", "origin_x": 0.125, "tool_level" : 1, - "max_stack": 60 + "max_stack": 60, + "burning_time": 10000 }, "stone_axe": { "name": "Stone Axe", @@ -1283,7 +1323,7 @@ }, "bucket_empty": { "name": "Empty Bucket", - "type": "bucket", + "type": "usable", "texture": "bucket_empty", "origin_x": 0.25, "action_key": "use_empty_bucket", @@ -1291,7 +1331,7 @@ }, "bucket_water": { "name": "Water Bucket", - "type": "bucket", + "type": "usable", "texture": "bucket_water", "origin_x": 0.25, "action_key": "use_water_bucket", @@ -1299,16 +1339,65 @@ }, "bucket_lava": { "name": "Lava Bucket", - "type": "bucket", + "type": "usable", "texture": "bucket_lava", "origin_x": 0.25, "action_key": "use_lava_bucket", - "max_stack": 1 + "max_stack": 1, + "burning_time": 1000000 }, "snowball": { "name": "Snowball", + "type": "usable", "texture": "snowball", + "action_key": "use_snow_ball_action", "max_stack": 16 + }, + "coal": { + "name": "Coal", + "texture": "coal", + "burning_time": 80000, + "origin_x": 0.25 + }, + "charcoal": { + "name": "Charcoal", + "texture": "charcoal", + "burning_time": 80000, + "origin_x": 0.25 + }, + "iron_ingot": { + "name": "Iron Ingot", + "texture": "iron_ingot", + "origin_x": 0.5 + }, + "gold_ingot": { + "name": "Gold Ingot", + "texture": "gold_ingot", + "origin_x": 0.5 + }, + "diamond": { + "name": "Diamond", + "texture": "diamond", + "origin_x": 0.5 + }, + "lapis_lazuli": { + "name": "Lapis Lazuli", + "texture": "lapis_lazuli", + "origin_x": 0.5 + }, + "bed": { + "name": "Bed", + "type": "usable", + "texture": "bed", + "action_key": "use_bed_action" + }, + "spawn_egg_pig": { + "name": "Pig Spawn Egg", + "type": "usable", + "texture": "spawn_egg", + "tint": "#EDBFB4", + "action_key": "use_spawn_egg_pig", + "origin_x": 0.5 } } } diff --git a/android/assets/json/texture_regions.json b/android/assets/json/texture_regions.json index 11459c3..1800acd 100644 --- a/android/assets/json/texture_regions.json +++ b/android/assets/json/texture_regions.json @@ -72,6 +72,23 @@ "h": 166 } }, + "furnace": { + "furnace": { + "w": 176, + "h": 166 + }, + "furnace_burn": { + "x": 176, + "w": 14, + "h": 14 + }, + "furnace_progress": { + "x": 176, + "y": 14, + "w": 24, + "h": 14 + } + }, "buttons": { "button_0": { "w": 200, diff --git a/android/assets/textures/blocks/furnace.png b/android/assets/textures/blocks/furnace.png new file mode 100644 index 0000000..080d8ad Binary files /dev/null and b/android/assets/textures/blocks/furnace.png differ diff --git a/android/assets/textures/blocks/furnace_off.png b/android/assets/textures/blocks/furnace_off.png deleted file mode 100644 index 6d9b405..0000000 Binary files a/android/assets/textures/blocks/furnace_off.png and /dev/null differ diff --git a/android/assets/textures/blocks/furnace_on.png b/android/assets/textures/blocks/furnace_on.png deleted file mode 100644 index ecbc607..0000000 Binary files a/android/assets/textures/blocks/furnace_on.png and /dev/null differ diff --git a/android/assets/textures/items/bed.png b/android/assets/textures/items/bed.png new file mode 100644 index 0000000..0e1565d Binary files /dev/null and b/android/assets/textures/items/bed.png differ diff --git a/android/assets/textures/items/diamond.png b/android/assets/textures/items/diamond.png new file mode 100644 index 0000000..eff11e0 Binary files /dev/null and b/android/assets/textures/items/diamond.png differ diff --git a/android/assets/textures/items/gold_ingot.png b/android/assets/textures/items/gold_ingot.png new file mode 100644 index 0000000..b159455 Binary files /dev/null and b/android/assets/textures/items/gold_ingot.png differ diff --git a/android/assets/textures/items/iron_ingot.png b/android/assets/textures/items/iron_ingot.png new file mode 100644 index 0000000..1ff5c69 Binary files /dev/null and b/android/assets/textures/items/iron_ingot.png differ diff --git a/android/assets/textures/items/lapis_lazuli.png b/android/assets/textures/items/lapis_lazuli.png new file mode 100644 index 0000000..84bdcd4 Binary files /dev/null and b/android/assets/textures/items/lapis_lazuli.png differ diff --git a/android/assets/textures/items/spawn_egg.png b/android/assets/textures/items/spawn_egg.png new file mode 100644 index 0000000..8733a83 Binary files /dev/null and b/android/assets/textures/items/spawn_egg.png differ diff --git a/android/assets/touch_gui.png b/android/assets/touch_gui.png index 62e4af5..57dffc4 100644 Binary files a/android/assets/touch_gui.png and b/android/assets/touch_gui.png differ diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameModule.java b/core/src/ru/deadsoftware/cavedroid/game/GameModule.java index fbbd294..2385230 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameModule.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameModule.java @@ -5,7 +5,8 @@ import dagger.Provides; import ru.deadsoftware.cavedroid.MainConfig; import ru.deadsoftware.cavedroid.game.mobs.MobsController; import ru.deadsoftware.cavedroid.game.model.block.Block; -import ru.deadsoftware.cavedroid.game.objects.DropController; +import ru.deadsoftware.cavedroid.game.objects.drop.DropController; +import ru.deadsoftware.cavedroid.game.objects.furnace.FurnaceController; import ru.deadsoftware.cavedroid.game.ui.TooltipManager; import ru.deadsoftware.cavedroid.game.world.GameWorld; @@ -43,6 +44,16 @@ public class GameModule { return controller; } + @Provides + @GameScope + public static FurnaceController provideFurnaceController(MainConfig mainConfig, GameItemsHolder gameItemsHolder) { + load(mainConfig, gameItemsHolder); + FurnaceController controller = data != null ? data.retrueveFurnaceController() : new FurnaceController(); + makeDataNullIfEmpty(); + controller.init(gameItemsHolder); + return controller; + } + @Provides @GameScope public static MobsController provideMobsController(MainConfig mainConfig, @@ -62,12 +73,13 @@ public class GameModule { public static GameWorld provideGameWorld(MainConfig mainConfig, DropController dropController, MobsController mobsController, - GameItemsHolder gameItemsHolder) { + GameItemsHolder gameItemsHolder, + FurnaceController furnaceController) { load(mainConfig, gameItemsHolder); Block[][] fm = data != null ? data.retrieveForeMap() : null; Block[][] bm = data != null ? data.retrieveBackMap() : null; makeDataNullIfEmpty(); - return new GameWorld(dropController, mobsController, gameItemsHolder, fm, bm); + return new GameWorld(dropController, mobsController, gameItemsHolder, furnaceController, fm, bm); } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/GamePhysics.java b/core/src/ru/deadsoftware/cavedroid/game/GamePhysics.java index eee83c7..aebf8eb 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GamePhysics.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GamePhysics.java @@ -9,8 +9,8 @@ import ru.deadsoftware.cavedroid.game.mobs.Mob; import ru.deadsoftware.cavedroid.game.mobs.MobsController; import ru.deadsoftware.cavedroid.game.mobs.player.Player; import ru.deadsoftware.cavedroid.game.model.block.Block; -import ru.deadsoftware.cavedroid.game.objects.Drop; -import ru.deadsoftware.cavedroid.game.objects.DropController; +import ru.deadsoftware.cavedroid.game.objects.drop.Drop; +import ru.deadsoftware.cavedroid.game.objects.drop.DropController; import ru.deadsoftware.cavedroid.game.world.GameWorld; import javax.annotation.CheckForNull; diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameProc.java b/core/src/ru/deadsoftware/cavedroid/game/GameProc.java index d797680..a3fcabb 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameProc.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameProc.java @@ -6,6 +6,7 @@ import com.badlogic.gdx.utils.Timer; import ru.deadsoftware.cavedroid.MainConfig; import ru.deadsoftware.cavedroid.game.mobs.MobsController; import ru.deadsoftware.cavedroid.game.mobs.player.Player; +import ru.deadsoftware.cavedroid.game.objects.furnace.FurnaceController; import ru.deadsoftware.cavedroid.game.world.GameWorldBlocksLogicControllerTask; import ru.deadsoftware.cavedroid.game.world.GameWorldFluidsLogicControllerTask; import ru.deadsoftware.cavedroid.game.world.GameWorldMobDamageControllerTask; @@ -18,6 +19,8 @@ public class GameProc implements Disposable { private final GamePhysics mGamePhysics; private final GameRenderer mGameRenderer; private final MobsController mMobsController; + private final FurnaceController mFurnaceController; + private final GameItemsHolder mGameItemsHolder; private final GameWorldFluidsLogicControllerTask mGameWorldFluidsLogicControllerTask; private final GameWorldBlocksLogicControllerTask mGameWorldBlocksLogicControllerTask; private final GameWorldMobDamageControllerTask mGameWorldMobDamageControllerTask; @@ -29,6 +32,8 @@ public class GameProc implements Disposable { GamePhysics gamePhysics, GameRenderer gameRenderer, MobsController mobsController, + FurnaceController furnaceController, + GameItemsHolder gameItemsHolder, GameWorldFluidsLogicControllerTask gameWorldFluidsLogicControllerTask, GameWorldBlocksLogicControllerTask gameWorldBlocksLogicControllerTask, GameWorldMobDamageControllerTask gameWorldMobDamageControllerTask @@ -36,6 +41,8 @@ public class GameProc implements Disposable { mGamePhysics = gamePhysics; mGameRenderer = gameRenderer; mMobsController = mobsController; + mFurnaceController = furnaceController; + mGameItemsHolder = gameItemsHolder; mGameWorldFluidsLogicControllerTask = gameWorldFluidsLogicControllerTask; mGameWorldBlocksLogicControllerTask = gameWorldBlocksLogicControllerTask; mGameWorldMobDamageControllerTask = gameWorldMobDamageControllerTask; @@ -57,6 +64,7 @@ public class GameProc implements Disposable { public void update(float delta) { mGamePhysics.update(delta); mGameRenderer.render(delta); + mFurnaceController.update(mGameItemsHolder); } public void show() { diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java b/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java index 36f6c75..2ae4756 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java @@ -109,7 +109,9 @@ public class GameRenderer extends Renderer { float camTargetX, camTargetY; - if (player.controlMode == Player.ControlMode.WALK) { + boolean followPlayer = player.controlMode == Player.ControlMode.WALK || !mMainConfig.isTouch(); + + if (followPlayer) { camTargetX = plTargetX + Math.min(player.getVelocity().x * 2, getWidth() / 2); camTargetY = plTargetY + player.getVelocity().y; } else { @@ -119,7 +121,7 @@ public class GameRenderer extends Renderer { Vector2 moveVector = new Vector2(camTargetX - camCenterX, camTargetY - camCenterY); - if (player.controlMode == Player.ControlMode.WALK && player.getVelocity().isZero()) { + if (followPlayer && player.getVelocity().isZero()) { mCameraDelayMs = TimeUtils.millis(); mCamCenterToPlayer.x = plTargetX - camCenterX; mCamCenterToPlayer.y = plTargetY - camCenterY; diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java b/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java index cb52b3c..dd16186 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java @@ -5,7 +5,8 @@ import com.badlogic.gdx.files.FileHandle; import ru.deadsoftware.cavedroid.MainConfig; import ru.deadsoftware.cavedroid.game.mobs.MobsController; import ru.deadsoftware.cavedroid.game.model.block.Block; -import ru.deadsoftware.cavedroid.game.objects.DropController; +import ru.deadsoftware.cavedroid.game.objects.drop.DropController; +import ru.deadsoftware.cavedroid.game.objects.furnace.FurnaceController; import ru.deadsoftware.cavedroid.game.world.GameWorld; import javax.annotation.CheckForNull; @@ -24,11 +25,18 @@ public class GameSaver { @CheckForNull private DropController mDropController; @CheckForNull + private FurnaceController mFurnaceController; + @CheckForNull private Block[][] mForeMap, mBackMap; - public Data(MobsController mobsController, DropController dropController, Block[][] foreMap, Block[][] backMap) { + public Data(MobsController mobsController, + DropController dropController, + FurnaceController furnaceController, + Block[][] foreMap, + Block[][] backMap) { mMobsController = mobsController; mDropController = dropController; + mFurnaceController = furnaceController; mForeMap = foreMap; mBackMap = backMap; } @@ -47,6 +55,13 @@ public class GameSaver { return dropController; } + public FurnaceController retrueveFurnaceController() { + assert mFurnaceController != null; + FurnaceController furnaceController = mFurnaceController; + mFurnaceController = null; + return furnaceController; + } + public Block[][] retrieveForeMap() { assert mForeMap != null; Block[][] foreMap = mForeMap; @@ -183,10 +198,12 @@ public class GameSaver { int version = in.readInt(); DropController dropController; MobsController mobsController; + FurnaceController furnaceController; if (SAVE_VERSION == version) { dropController = (DropController) in.readObject(); mobsController = (MobsController) in.readObject(); + furnaceController = (FurnaceController) in.readObject(); } else { throw new Exception("version mismatch"); } @@ -201,7 +218,7 @@ public class GameSaver { throw new Exception("couldn't load"); } - return new Data(mobsController, dropController, foreMap, backMap); + return new Data(mobsController, dropController, furnaceController, foreMap, backMap); } catch (Exception e) { Gdx.app.error("GameSaver", e.getMessage()); } @@ -212,6 +229,7 @@ public class GameSaver { public static void save(MainConfig mainConfig, DropController dropController, MobsController mobsController, + FurnaceController furnaceController, GameWorld gameWorld) { String folder = mainConfig.getGameFolder(); FileHandle file = Gdx.files.absolute(folder + "/saves/"); @@ -229,6 +247,7 @@ public class GameSaver { out.writeInt(SAVE_VERSION); out.writeObject(dropController); out.writeObject(mobsController); + out.writeObject(furnaceController); out.close(); saveDict(Gdx.files.absolute(folder + "/saves/dict"), dict); diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt index 76127fa..5b2a169 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt @@ -7,6 +7,7 @@ import dagger.multibindings.StringKey import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.actions.useblock.IUseBlockAction import ru.deadsoftware.cavedroid.game.actions.useblock.UseCraftingTableAction +import ru.deadsoftware.cavedroid.game.actions.useblock.UseFurnaceAction @Module class UseBlockActionsModule { @@ -18,4 +19,12 @@ class UseBlockActionsModule { fun bindUseCraftingTableAction(action: UseCraftingTableAction): IUseBlockAction { return action } + + @Binds + @IntoMap + @StringKey(UseFurnaceAction.KEY) + @GameScope + fun bindUseFurnaceTableAction(action: UseFurnaceAction): IUseBlockAction { + return action + } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt index 0206d5f..a6aed22 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt @@ -34,4 +34,12 @@ class UseItemActionsModule { return action } + @Binds + @IntoMap + @StringKey(UsePigSpawnEggAction.ACTION_KEY) + @GameScope + fun bindUsePigSpawnEgg(action: UsePigSpawnEggAction): IUseItemAction { + return action + } + } diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt new file mode 100644 index 0000000..88a6a7f --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt @@ -0,0 +1,23 @@ +package ru.deadsoftware.cavedroid.game.actions.useblock + +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.model.block.Block +import ru.deadsoftware.cavedroid.game.objects.furnace.FurnaceController +import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager +import javax.inject.Inject + +@GameScope +class UseFurnaceAction @Inject constructor( + private val furnaceController: FurnaceController, + private val gameWindowsManager: GameWindowsManager, +) : IUseBlockAction { + + override fun perform(block: Block, x: Int, y: Int) { + val furnace = furnaceController.getFurnace(x, y, 0) ?: furnaceController.getFurnace(x, y, 1) ?: return + gameWindowsManager.openFurnace(furnace) + } + + companion object { + const val KEY = "furnace" + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UsePigSpawnEggAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UsePigSpawnEggAction.kt new file mode 100644 index 0000000..0c50d15 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UsePigSpawnEggAction.kt @@ -0,0 +1,27 @@ +package ru.deadsoftware.cavedroid.game.actions.useitem + +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.mobs.Pig +import ru.deadsoftware.cavedroid.game.model.item.Item +import ru.deadsoftware.cavedroid.misc.utils.px +import javax.inject.Inject + +@GameScope +class UsePigSpawnEggAction @Inject constructor( + private val mobsController: MobsController, +) : IUseItemAction { + + override fun perform(item: Item.Usable, x: Int, y: Int) { + Pig(mobsController.player.cursorX.px, mobsController.player.cursorY.px) + .apply { + attachToController(mobsController) + } + + mobsController.player.inventory.decreaseCurrentItemAmount() + } + + companion object { + const val ACTION_KEY = "use_spawn_egg_pig" + } +} diff --git a/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt b/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt index 0886a07..df1dd06 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt @@ -3,7 +3,7 @@ package ru.deadsoftware.cavedroid.game.debug import com.badlogic.gdx.Gdx import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.MobsController -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt b/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt index 3d5f32a..fe9bba6 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt @@ -74,6 +74,13 @@ object MouseInputHandlersModule { return handler } + @Binds + @IntoSet + @GameScope + fun bindSelectFurnaceInventoryItemMouseInputHandler(handler: SelectFurnaceInventoryItemMouseInputHandler): IGameInputHandler { + return handler + } + @Binds @IntoSet @GameScope diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt index 6a8f019..89a7b69 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt @@ -6,7 +6,7 @@ import ru.deadsoftware.cavedroid.game.input.IGameInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import javax.inject.Inject diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt index b46812c..04f5520 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt @@ -7,8 +7,8 @@ import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.item.Item -import ru.deadsoftware.cavedroid.game.objects.Drop -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.Drop +import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import javax.inject.Inject diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt index ce70054..ec8190a 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt @@ -5,8 +5,6 @@ import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.input.IGameInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey -import ru.deadsoftware.cavedroid.game.mobs.MobsController -import ru.deadsoftware.cavedroid.game.objects.DropController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import javax.inject.Inject diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt index 60a9edf..8ba35c1 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt @@ -7,7 +7,8 @@ import ru.deadsoftware.cavedroid.game.input.IGameInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.DropController +import ru.deadsoftware.cavedroid.game.objects.furnace.FurnaceController import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @@ -17,6 +18,7 @@ class PauseGameKeyboardInputHandler @Inject constructor( private val dropController: DropController, private val mobsController: MobsController, private val gameWorld: GameWorld, + private val furnaceController: FurnaceController, ) : IGameInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { @@ -24,7 +26,7 @@ class PauseGameKeyboardInputHandler @Inject constructor( } override fun handle(action: KeyboardInputAction) { - GameSaver.save(mainConfig, dropController, mobsController, gameWorld) + GameSaver.save(mainConfig, dropController, mobsController, furnaceController, gameWorld) mainConfig.caveGame.quitGame() } } \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt index ffda344..ddc41e2 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt @@ -9,7 +9,7 @@ import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideWindow import ru.deadsoftware.cavedroid.game.mobs.MobsController -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject @@ -23,6 +23,7 @@ class CloseGameWindowMouseInputHandler @Inject constructor( private val creativeInventoryTexture get() = requireNotNull(Assets.textureRegions["creative"]) private val survivalInventoryTexture get() = requireNotNull(Assets.textureRegions["survival"]) private val craftingInventoryTexture get() = requireNotNull(Assets.textureRegions["crafting_table"]) + private val furnaceInventoryTexture get() = requireNotNull(Assets.textureRegions["furnace"]) override fun checkConditions(action: MouseInputAction): Boolean { return gameWindowsManager.getCurrentWindow() != GameUiWindow.NONE && @@ -36,6 +37,7 @@ class CloseGameWindowMouseInputHandler @Inject constructor( GameUiWindow.CREATIVE_INVENTORY -> creativeInventoryTexture GameUiWindow.SURVIVAL_INVENTORY -> survivalInventoryTexture GameUiWindow.CRAFTING_TABLE -> craftingInventoryTexture + GameUiWindow.FURNACE -> furnaceInventoryTexture else -> throw UnsupportedOperationException("Cant close window ${window.name}") } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt index 6b86c8b..18cd41d 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt @@ -12,8 +12,8 @@ import ru.deadsoftware.cavedroid.game.input.isInsideHotbar import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.mobs.player.Player import ru.deadsoftware.cavedroid.game.model.item.Item -import ru.deadsoftware.cavedroid.game.objects.Drop -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.Drop +import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt index 1b4838a..32c7a43 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt @@ -10,7 +10,7 @@ import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideWindow import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.item.InventoryItem -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import ru.deadsoftware.cavedroid.game.ui.windows.inventory.CraftingInventoryWindow diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectFurnaceInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectFurnaceInventoryItemMouseInputHandler.kt new file mode 100644 index 0000000..839135e --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectFurnaceInventoryItemMouseInputHandler.kt @@ -0,0 +1,172 @@ +package ru.deadsoftware.cavedroid.game.input.handler.mouse + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.utils.TimeUtils +import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey +import ru.deadsoftware.cavedroid.game.input.isInsideWindow +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem.Companion.isNoneOrNull +import ru.deadsoftware.cavedroid.game.objects.drop.DropController +import ru.deadsoftware.cavedroid.game.objects.furnace.Furnace +import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs +import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.game.ui.windows.inventory.FurnaceInventoryWindow +import ru.deadsoftware.cavedroid.misc.Assets +import javax.inject.Inject + +@GameScope +class SelectFurnaceInventoryItemMouseInputHandler @Inject constructor( + private val gameWindowsManager: GameWindowsManager, + private val mobsController: MobsController, + private val gameItemsHolder: GameItemsHolder, + private val dropController: DropController, +) : IGameInputHandler { + + private val survivalWindowTexture get() = requireNotNull(Assets.textureRegions["survival"]) + + override fun checkConditions(action: MouseInputAction): Boolean { + return gameWindowsManager.getCurrentWindow() == GameUiWindow.FURNACE && + isInsideWindow(action, survivalWindowTexture) && + (action.actionKey is MouseInputActionKey.Left || action.actionKey is MouseInputActionKey.Right || action.actionKey is MouseInputActionKey.Screen) + && (action.actionKey.touchUp || action.actionKey is MouseInputActionKey.Screen) + } + + private fun handleInsideInventoryGrid(action: MouseInputAction, xOnGrid: Int, yOnGrid: Int) { + val window = gameWindowsManager.currentWindow as FurnaceInventoryWindow + + var itemIndex = ((xOnGrid.toInt() + yOnGrid.toInt() * GameWindowsConfigs.Furnace.itemsInRow)) + itemIndex += GameWindowsConfigs.Furnace.hotbarCells + + if (itemIndex >= mobsController.player.inventory.size) { + itemIndex -= mobsController.player.inventory.size + } + + if (action.actionKey is MouseInputActionKey.Screen) { + if (!action.actionKey.touchUp) { + window.onLeftCLick(mobsController.player.inventory.items as MutableList, gameItemsHolder, itemIndex, action.actionKey.pointer) + } else { + if (action.actionKey.pointer == window.selectItemPointer) { + window.onLeftCLick(mobsController.player.inventory.items as MutableList, gameItemsHolder, itemIndex, action.actionKey.pointer) + } else { + window.onRightClick(mobsController.player.inventory.items as MutableList, itemIndex) + } + } + } else if (action.actionKey is MouseInputActionKey.Left) { + window.onLeftCLick(mobsController.player.inventory.items as MutableList, gameItemsHolder, itemIndex) + } else { + window.onRightClick(mobsController.player.inventory.items as MutableList, itemIndex) + } + + Gdx.app.debug( + TAG, + "selected item: ${window.selectedItem?.item?.params?.key ?: "null"}; index $itemIndex, grid ($xOnGrid;$yOnGrid)" + ) + } + + private fun handleInsideFuel(action: MouseInputAction) { + val window = gameWindowsManager.currentWindow as FurnaceInventoryWindow + + if (!window.selectedItem.isNoneOrNull() && window.selectedItem?.item?.params?.burningTimeMs == null) { + return + } + + if (action.actionKey is MouseInputActionKey.Screen) { + if (!action.actionKey.touchUp) { + window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.FUEL_INDEX, action.actionKey.pointer) + } else { + if (action.actionKey.pointer == window.selectItemPointer) { + window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.FUEL_INDEX, action.actionKey.pointer) + } else { + window.onRightClick(window.furnace.items, Furnace.FUEL_INDEX) + } + } + } else if (action.actionKey is MouseInputActionKey.Left || action.actionKey is MouseInputActionKey.Screen) { + window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.FUEL_INDEX) + } else { + window.onRightClick(window.furnace.items, Furnace.FUEL_INDEX) + } + } + + private fun handleInsideInput(action: MouseInputAction) { + val window = gameWindowsManager.currentWindow as FurnaceInventoryWindow + + if (action.actionKey is MouseInputActionKey.Screen) { + if (!action.actionKey.touchUp) { + window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.INPUT_INDEX, action.actionKey.pointer) + } else { + if (action.actionKey.pointer == window.selectItemPointer) { + window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.INPUT_INDEX, action.actionKey.pointer) + } else { + window.onRightClick(window.furnace.items, Furnace.INPUT_INDEX) + } + } + } else if (action.actionKey is MouseInputActionKey.Left || action.actionKey is MouseInputActionKey.Screen) { + window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.INPUT_INDEX) + } else { + window.onRightClick(window.furnace.items, Furnace.INPUT_INDEX) + } + } + + override fun handle(action: MouseInputAction) { + val survivalTexture = survivalWindowTexture + val window = gameWindowsManager.currentWindow as FurnaceInventoryWindow + + val xOnWindow = action.screenX - (action.cameraViewport.width / 2 - survivalTexture.regionWidth / 2) + val yOnWindow = action.screenY - (action.cameraViewport.height / 2 - survivalTexture.regionHeight / 2) + + val xOnGrid = (xOnWindow - GameWindowsConfigs.Furnace.itemsGridMarginLeft) / + GameWindowsConfigs.Furnace.itemsGridColWidth + val yOnGrid = (yOnWindow - GameWindowsConfigs.Furnace.itemsGridMarginTop) / + GameWindowsConfigs.Furnace.itemsGridRowHeight + + val isInsideInput = xOnWindow > GameWindowsConfigs.Furnace.smeltInputMarginLeft && + xOnWindow < GameWindowsConfigs.Furnace.smeltInputMarginLeft + GameWindowsConfigs.Furnace.itemsGridColWidth && + yOnWindow > GameWindowsConfigs.Furnace.smeltInputMarginTop && + yOnWindow < GameWindowsConfigs.Furnace.smeltInputMarginTop + GameWindowsConfigs.Furnace.itemsGridRowHeight + + val isInsideFuel = xOnWindow > GameWindowsConfigs.Furnace.smeltFuelMarginLeft && + xOnWindow < GameWindowsConfigs.Furnace.smeltFuelMarginLeft + GameWindowsConfigs.Furnace.itemsGridColWidth && + yOnWindow > GameWindowsConfigs.Furnace.smeltFuelMarginTop && + yOnWindow < GameWindowsConfigs.Furnace.smeltFuelMarginTop + GameWindowsConfigs.Furnace.itemsGridRowHeight + + val isInsideResult = xOnWindow > GameWindowsConfigs.Furnace.smeltResultOffsetX && + xOnWindow < GameWindowsConfigs.Furnace.smeltResultOffsetX + GameWindowsConfigs.Furnace.itemsGridColWidth && + yOnWindow > GameWindowsConfigs.Furnace.smeltResultOffsetY && + yOnWindow < GameWindowsConfigs.Furnace.smeltResultOffsetY + GameWindowsConfigs.Furnace.itemsGridRowHeight + + val isInsideInventoryGrid = xOnGrid >= 0 && xOnGrid < GameWindowsConfigs.Furnace.itemsInRow && + yOnGrid >= 0 && yOnGrid < GameWindowsConfigs.Furnace.itemsInCol + + if (isInsideInventoryGrid) { + handleInsideInventoryGrid(action, xOnGrid.toInt(), yOnGrid.toInt()) + } else if (isInsideFuel) { + handleInsideFuel(action) + } else if (isInsideInput) { + handleInsideInput(action) + } else if (isInsideResult && action.actionKey.touchUp) { + val selectedItem = window.selectedItem + if (selectedItem == null || selectedItem.item.isNone() || + (selectedItem.item == window.furnace.result?.item && selectedItem.amount + (window.furnace.result?.amount ?: 0) <= selectedItem.item.params.maxStack)) { + + if (selectedItem != null && !selectedItem.item.isNone()) { + selectedItem.amount += (window.furnace.result?.amount ?: 0) + } else { + window.selectedItem = window.furnace.result + } + window.furnace.items[Furnace.RESULT_INDEX] = null + } + } + + } + + companion object { + private const val TAG = "SelectFurnaceInventoryItemMouseInputHandler" + + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt index 91ec311..263d59e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt @@ -10,7 +10,7 @@ import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideWindow import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.item.InventoryItem -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import ru.deadsoftware.cavedroid.game.ui.windows.inventory.SurvivalInventoryWindow diff --git a/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Inventory.kt b/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Inventory.kt index 8ce9592..c5e10d0 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Inventory.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Inventory.kt @@ -3,7 +3,7 @@ package ru.deadsoftware.cavedroid.game.mobs.player import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.model.item.InventoryItem import ru.deadsoftware.cavedroid.game.model.item.Item -import ru.deadsoftware.cavedroid.game.objects.Drop +import ru.deadsoftware.cavedroid.game.objects.drop.Drop import ru.deadsoftware.cavedroid.game.ui.TooltipManager import java.io.Serializable diff --git a/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Player.java b/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Player.java index 5fcfe31..40b7c79 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Player.java +++ b/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Player.java @@ -9,8 +9,8 @@ import ru.deadsoftware.cavedroid.game.mobs.Mob; import ru.deadsoftware.cavedroid.game.model.block.Block; import ru.deadsoftware.cavedroid.game.model.item.InventoryItem; import ru.deadsoftware.cavedroid.game.model.item.Item; -import ru.deadsoftware.cavedroid.game.objects.Drop; -import ru.deadsoftware.cavedroid.game.objects.DropController; +import ru.deadsoftware.cavedroid.game.objects.drop.Drop; +import ru.deadsoftware.cavedroid.game.objects.drop.DropController; import ru.deadsoftware.cavedroid.game.ui.TooltipManager; import ru.deadsoftware.cavedroid.game.world.GameWorld; import ru.deadsoftware.cavedroid.misc.Assets; 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 76c6ac5..2e268d0 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/block/Block.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/block/Block.kt @@ -20,14 +20,14 @@ sealed class Block { val spriteWidth: Float get() = 16f - params.spriteMargins.left - params.spriteMargins.right val spriteHeight: Float get() = 16f - params.spriteMargins.top - params.spriteMargins.bottom - private var animation: Array? = null + protected var animation: Array? = null private var _sprite: Sprite? = null get() { return animation?.get(currentAnimationFrame) ?: field } - val sprite: Sprite + open val sprite: Sprite get() = requireNotNull(_sprite) { "null sprite for block '${params.key}'" } private val currentAnimationFrame: Int @@ -111,6 +111,11 @@ sealed class Block { return this is Slab } + fun isFurnace(): Boolean { + contract { returns(true) implies (this@Block is Furnace) } + return this is Furnace + } + fun isNone(): Boolean { contract { returns(true) implies (this@Block is None) } return this is None @@ -133,6 +138,37 @@ sealed class Block { override val params: CommonBlockParams, ) : Block() + data class Furnace( + override val params: CommonBlockParams, + ): Block() { + + override val sprite: Sprite + get() = getSprite(false) + + private fun getSprite(isActive: Boolean): Sprite { + return animation?.let { animation -> + if (isActive) { + animation[1] + } else { + animation[0] + } + } ?: sprite + } + + fun draw(spriter: SpriteBatch, x: Float, y: Float, isActive: Boolean) { + getSprite(isActive).apply { + setBounds( + /* x = */ x + params.spriteMargins.left, + /* y = */ y + params.spriteMargins.top, + /* width = */ spriteWidth, + /* height = */ spriteHeight + ) + draw(spriter) + } + } + + } + data class Slab( override val params: CommonBlockParams, val fullBlockKey: String, diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/dto/ItemDto.kt b/core/src/ru/deadsoftware/cavedroid/game/model/dto/ItemDto.kt index f3c0544..373db46 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/dto/ItemDto.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/dto/ItemDto.kt @@ -17,4 +17,7 @@ data class ItemDto( @SerialName("bottom_slab_block") val bottomSlabBlock: String? = null, @SerialName("tool_level") val toolLevel: Int? = null, @SerialName("max_stack") val maxStack: Int = 64, + @SerialName("tint") val tint: String? = null, + @SerialName("burning_time") val burningTime: Long? = null, + @SerialName("smelt_product") val smeltProduct: String? = null, ) diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/item/CommonItemParams.kt b/core/src/ru/deadsoftware/cavedroid/game/model/item/CommonItemParams.kt index 0330a36..00af08b 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/item/CommonItemParams.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/item/CommonItemParams.kt @@ -7,4 +7,6 @@ data class CommonItemParams( val name: String, val inHandSpriteOrigin: SpriteOrigin, val maxStack: Int, + val burningTimeMs: Long?, + val smeltProductKey: String?, ) \ No newline at end of file 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 7652243..acc0d29 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/item/InventoryItem.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/item/InventoryItem.kt @@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.ShapeRenderer import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.mobs.player.Inventory import ru.deadsoftware.cavedroid.misc.Assets import ru.deadsoftware.cavedroid.misc.utils.drawSprite import ru.deadsoftware.cavedroid.misc.utils.drawString @@ -119,4 +120,7 @@ class InventoryItem @JvmOverloads constructor( } } + companion object { + fun InventoryItem?.isNoneOrNull() = this?.item == null || this.item.isNone() + } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/item/Item.kt b/core/src/ru/deadsoftware/cavedroid/game/model/item/Item.kt index 1e6755a..bf2a55c 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/item/Item.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/item/Item.kt @@ -46,8 +46,8 @@ sealed class Item { } fun isUsable(): Boolean { - contract { returns(true) implies (this@Item is Placeable) } - return this is Placeable + contract { returns(true) implies (this@Item is Usable) } + return this is Usable } @JvmOverloads @@ -66,10 +66,6 @@ sealed class Item { abstract val level: Int } - sealed class Usable : Item() { - abstract val useActionKey: String - } - sealed class Placeable : Item() { abstract val block: BlockModel override val sprite: Sprite get() = block.sprite @@ -82,6 +78,12 @@ sealed class Item { get() = throw IllegalAccessException("Trying to get sprite of None") } + data class Usable( + override val params: CommonItemParams, + override val sprite: Sprite, + val useActionKey: String + ) : Item() + data class Block( override val params: CommonItemParams, override val block: BlockModel @@ -134,11 +136,5 @@ sealed class Item { override val blockDamageMultiplier: Float, override val level: Int, ) : Tool() - - data class Bucket( - override val params: CommonItemParams, - override val sprite: Sprite, - override val useActionKey: String - ) : Usable() } \ No newline at end of file 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 f45451f..2ec9727 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/mapper/BlockMapper.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/mapper/BlockMapper.kt @@ -23,6 +23,7 @@ class BlockMapper @Inject constructor( "water" -> Water(commonBlockParams, requireNotNull(dto.state)) "lava" -> Lava(commonBlockParams, requireNotNull(dto.state)) "slab" -> Slab(commonBlockParams, requireNotNull(dto.fullBlock), requireNotNull(dto.otherPart)) + "furnace" -> Furnace(commonBlockParams) "none" -> None(commonBlockParams) else -> Normal(commonBlockParams) } diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/mapper/ItemMapper.kt b/core/src/ru/deadsoftware/cavedroid/game/model/mapper/ItemMapper.kt index 4557cc8..a0949a0 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/mapper/ItemMapper.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/mapper/ItemMapper.kt @@ -11,6 +11,7 @@ import ru.deadsoftware.cavedroid.game.model.item.Item.* import ru.deadsoftware.cavedroid.misc.Assets import ru.deadsoftware.cavedroid.misc.utils.AssetLoader import ru.deadsoftware.cavedroid.misc.utils.SpriteOrigin +import ru.deadsoftware.cavedroid.misc.utils.colorFromHexString import javax.inject.Inject @Reusable @@ -23,7 +24,7 @@ class ItemMapper @Inject constructor( return when (dto.type) { "normal" -> Normal(params, requireNotNull(loadSprite(dto))) - "bucket" -> Bucket(params, requireNotNull(loadSprite(dto)), requireNotNull(dto.actionKey)) + "usable" -> Usable(params, requireNotNull(loadSprite(dto)), requireNotNull(dto.actionKey)) "shovel" -> Shovel(params, requireNotNull(loadSprite(dto)), dto.mobDamageMultiplier, dto.blockDamageMultiplier, requireNotNull(dto.toolLevel)) "sword" -> Sword(params, requireNotNull(loadSprite(dto)), dto.mobDamageMultiplier, dto.blockDamageMultiplier, requireNotNull(dto.toolLevel)) "pickaxe" -> Pickaxe(params, requireNotNull(loadSprite(dto)), dto.mobDamageMultiplier, dto.blockDamageMultiplier, requireNotNull(dto.toolLevel)) @@ -45,6 +46,8 @@ class ItemMapper @Inject constructor( y = dto.origin_y, ), maxStack = dto.maxStack, + burningTimeMs = dto.burningTime, + smeltProductKey = dto.smeltProduct, ) } @@ -55,7 +58,12 @@ class ItemMapper @Inject constructor( val texture = Assets.resolveItemTexture(assetLoader, dto.texture) return Sprite(texture) - .apply { flip(false, true) } + .apply { + flip(false, true) + dto.tint?.let { + color = colorFromHexString(it) + } + } } } \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/Drop.kt b/core/src/ru/deadsoftware/cavedroid/game/objects/drop/Drop.kt similarity index 96% rename from core/src/ru/deadsoftware/cavedroid/game/objects/Drop.kt rename to core/src/ru/deadsoftware/cavedroid/game/objects/drop/Drop.kt index f67c66c..9099864 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/objects/Drop.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/objects/drop/Drop.kt @@ -1,4 +1,4 @@ -package ru.deadsoftware.cavedroid.game.objects +package ru.deadsoftware.cavedroid.game.objects.drop import com.badlogic.gdx.math.Intersector import com.badlogic.gdx.math.Rectangle diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/DropController.java b/core/src/ru/deadsoftware/cavedroid/game/objects/drop/DropController.java similarity index 79% rename from core/src/ru/deadsoftware/cavedroid/game/objects/DropController.java rename to core/src/ru/deadsoftware/cavedroid/game/objects/drop/DropController.java index e111f9c..6666fc8 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/objects/DropController.java +++ b/core/src/ru/deadsoftware/cavedroid/game/objects/drop/DropController.java @@ -1,7 +1,9 @@ -package ru.deadsoftware.cavedroid.game.objects; +package ru.deadsoftware.cavedroid.game.objects.drop; +import org.jetbrains.annotations.NotNull; import ru.deadsoftware.cavedroid.game.GameItemsHolder; import ru.deadsoftware.cavedroid.game.GameScope; +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem; import ru.deadsoftware.cavedroid.game.model.item.Item; import javax.inject.Inject; @@ -37,6 +39,10 @@ public class DropController implements Serializable { mDrops.add(new Drop(x, y, item, count)); } + public void addDrop(float x, float y, @NotNull InventoryItem invItem) { + addDrop(x, y, invItem.getItem(), invItem.getAmount()); + } + public int getSize() { return mDrops.size(); } diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/Furnace.kt b/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/Furnace.kt new file mode 100644 index 0000000..a6915ef --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/Furnace.kt @@ -0,0 +1,147 @@ +package ru.deadsoftware.cavedroid.game.objects.furnace + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.math.MathUtils +import com.badlogic.gdx.utils.TimeUtils +import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem.Companion.isNoneOrNull +import ru.deadsoftware.cavedroid.game.model.item.Item +import java.io.Serializable + +class Furnace : Serializable { + + val items = MutableList(3) { null } + + var fuel: InventoryItem? + get() = items[FUEL_INDEX] + set(value) { + items[FUEL_INDEX] = value + } + + var input: InventoryItem? + get() = items[INPUT_INDEX] + set(value) { + items[INPUT_INDEX] = value + } + + var result: InventoryItem? + get() = items[RESULT_INDEX] + set(value) { + items[RESULT_INDEX] = value + } + + val isActive: Boolean get() = currentFuel != null + + @Transient + var currentFuel: Item? = null + set(value) { + currentFuelKey = value?.params?.key + field = value + } + + var currentFuelKey: String? = null + + private var startBurnTimeMs = 0L + private var smeltStarTimeMs = 0L + + var burnProgress = 0f + private set(value) { + field = MathUtils.clamp(value, 0f, 1f) + } + var smeltProgress = 0f + private set(value) { + field = MathUtils.clamp(value, 0f, 1f) + } + + fun init(gameItemsHolder: GameItemsHolder) { + currentFuel = currentFuelKey?.let { gameItemsHolder.getItem(it) } + items.forEach { it?.init(gameItemsHolder) } + } + + fun canSmelt(): Boolean { + return (result.isNoneOrNull() || (result?.item?.params?.key == input?.item?.params?.smeltProductKey) )&& + !input.isNoneOrNull() && input?.item?.params?.smeltProductKey != null && + (!fuel.isNoneOrNull() || burnProgress > 0f) + } + + private fun startBurning() { + requireNotNull(fuel?.item?.params?.burningTimeMs) { "Cant start burning without fuel" } + currentFuel = fuel!!.item + fuel!!.subtract() + if (fuel!!.amount <= 0) { + fuel = null + } + startBurnTimeMs = TimeUtils.millis() + burnProgress = 0f + } + + fun update(gameItemsHolder: GameItemsHolder) { + if (currentFuel?.isNone() == true) { + currentFuel = null + } + + currentFuel?.let { curFuel -> + val burningTimeMs = curFuel.params.burningTimeMs ?: run { + Gdx.app.error(TAG, "Burning item has no burning time. Item : ${curFuel.params.key}") + return + } + + if (TimeUtils.timeSinceMillis(startBurnTimeMs).toDouble() / burningTimeMs >= 0.01) { + burnProgress += 0.01f + startBurnTimeMs = TimeUtils.millis() + } + + } + + if (currentFuel != null && burnProgress >= 1f) { + if (canSmelt()) { + startBurning() + } else { + currentFuel = null + burnProgress = 0f + smeltProgress = 0f + } + } + + if (!canSmelt()) { + return + } + if (currentFuel == null && !fuel.isNoneOrNull()) { + startBurning() + smeltStarTimeMs = startBurnTimeMs + smeltProgress = 0f + } + + if ((TimeUtils.timeSinceMillis(smeltStarTimeMs).toDouble() / SMELTING_TIME_MS) >= 0.01) { + smeltProgress += 0.01f + smeltStarTimeMs = TimeUtils.millis() + } + + if (isActive && smeltProgress >= 1f) { + val res = gameItemsHolder.getItem(input!!.item.params.smeltProductKey!!) + if (result.isNoneOrNull()) { + result = res.toInventoryItem() + } else { + result!!.add() + } + input!!.subtract() + if (input!!.amount <= 0) { + input = null + } + smeltStarTimeMs = TimeUtils.millis() + smeltProgress = 0f + } + } + + companion object { + private const val TAG = "Furnace" + + const val FUEL_INDEX = 0 + const val INPUT_INDEX = 1 + const val RESULT_INDEX = 2 + + const val SMELTING_TIME_MS = 10000L + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/FurnaceController.kt b/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/FurnaceController.kt new file mode 100644 index 0000000..ccc3972 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/FurnaceController.kt @@ -0,0 +1,43 @@ +package ru.deadsoftware.cavedroid.game.objects.furnace + +import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.objects.drop.DropController +import ru.deadsoftware.cavedroid.misc.utils.px +import java.io.Serializable +import javax.inject.Inject + +@GameScope +class FurnaceController @Inject constructor() : Serializable { + + private val furnaceMap = mutableMapOf() + + fun init(gameItemsHolder: GameItemsHolder) { + furnaceMap.forEach { _, fur -> fur.init(gameItemsHolder) } + } + + fun getFurnace(x: Int, y: Int, z: Int): Furnace? { + return furnaceMap["$x;$y;$z"] + } + + fun addFurnace(x: Int, y: Int, z: Int) { + furnaceMap["$x;$y;$z"] = Furnace() + } + + fun destroyFurnace(x: Int, y: Int, z: Int, dropController: DropController) { + val furnace = furnaceMap.remove("$x;$y;$z") ?: return + val xPx = (x + .5f).px + val yPx = (y + .5f).px + + furnace.input?.let { dropController.addDrop(xPx, yPx, it) } + furnace.fuel?.let { dropController.addDrop(xPx, yPx, it) } + furnace.result?.let { dropController.addDrop(xPx, yPx, it) } + } + + fun update(gameItemsHolder: GameItemsHolder) { + furnaceMap.forEach { _, furnace -> + furnace.update(gameItemsHolder) + } + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/BlocksRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/BlocksRenderer.kt index 378ed7b..5af20e8 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/BlocksRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/BlocksRenderer.kt @@ -2,7 +2,6 @@ package ru.deadsoftware.cavedroid.game.render import com.badlogic.gdx.graphics.g2d.Sprite import com.badlogic.gdx.graphics.g2d.SpriteBatch -import com.badlogic.gdx.graphics.g2d.TextureRegion import com.badlogic.gdx.graphics.glutils.ShapeRenderer import com.badlogic.gdx.math.MathUtils import com.badlogic.gdx.math.Rectangle @@ -87,7 +86,11 @@ abstract class BlocksRenderer( if (foregroundBlock.canSeeThrough && !backgroundBlock.isNone()) { val drawX = x.px - viewport.x val drawY = y.px - viewport.y - backgroundBlock.draw(spriteBatch, drawX, drawY) + if (backgroundBlock.isFurnace()) { + backgroundBlock.draw(spriteBatch, drawX, drawY, gameWorld.getBackgroundFurnace(x, y)?.isActive ?: false) + } else { + backgroundBlock.draw(spriteBatch, drawX, drawY) + } } } @@ -97,7 +100,12 @@ abstract class BlocksRenderer( if (!foregroundBlock.isNone() && foregroundBlock.params.isBackground == background) { val drawX = x.px - viewport.x val drawY = y.px - viewport.y - foregroundBlock.draw(spriteBatch, drawX, drawY) + + if (foregroundBlock.isFurnace()) { + foregroundBlock.draw(spriteBatch, drawX, drawY, gameWorld.getForegroundFurnace(x, y)?.isActive ?: false) + } else { + foregroundBlock.draw(spriteBatch, drawX, drawY) + } } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt index a17bd61..f14d36b 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt @@ -4,7 +4,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.ShapeRenderer import com.badlogic.gdx.math.Rectangle import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.world.GameWorld import ru.deadsoftware.cavedroid.misc.utils.cycledInsideWorld import ru.deadsoftware.cavedroid.misc.utils.drawSprite diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt index 03df48f..f87c5bd 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt @@ -8,6 +8,7 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.render.windows.CraftingWindowRenderer import ru.deadsoftware.cavedroid.game.render.windows.CreativeWindowRenderer +import ru.deadsoftware.cavedroid.game.render.windows.FurnaceWindowRenderer import ru.deadsoftware.cavedroid.game.render.windows.SurvivalWindowRenderer import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import javax.inject.Inject @@ -18,6 +19,7 @@ class WindowsRenderer @Inject constructor( private val survivalWindowRenderer: SurvivalWindowRenderer, private val craftingWindowRenderer: CraftingWindowRenderer, private val gameWindowsManager: GameWindowsManager, + private val furnaceWindowRenderer: FurnaceWindowRenderer, ) : IGameRenderer { override val renderLayer get() = RENDER_LAYER @@ -27,6 +29,7 @@ class WindowsRenderer @Inject constructor( GameUiWindow.CREATIVE_INVENTORY -> creativeWindowRenderer.draw(spriteBatch, shapeRenderer, viewport, delta) GameUiWindow.SURVIVAL_INVENTORY -> survivalWindowRenderer.draw(spriteBatch, shapeRenderer, viewport, delta) GameUiWindow.CRAFTING_TABLE -> craftingWindowRenderer.draw(spriteBatch, shapeRenderer, viewport, delta) + GameUiWindow.FURNACE -> furnaceWindowRenderer.draw(spriteBatch, shapeRenderer, viewport, delta) GameUiWindow.NONE -> return else -> Gdx.app.error(TAG, "Cannot draw window: ${windowType.name}") } diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/windows/FurnaceWindowRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/windows/FurnaceWindowRenderer.kt new file mode 100644 index 0000000..a963502 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/render/windows/FurnaceWindowRenderer.kt @@ -0,0 +1,139 @@ +package ru.deadsoftware.cavedroid.game.render.windows + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import com.badlogic.gdx.graphics.glutils.ShapeRenderer +import com.badlogic.gdx.math.Rectangle +import com.badlogic.gdx.utils.TimeUtils +import ru.deadsoftware.cavedroid.MainConfig +import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.objects.furnace.Furnace +import ru.deadsoftware.cavedroid.game.render.IGameRenderer +import ru.deadsoftware.cavedroid.game.render.WindowsRenderer +import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs +import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.game.ui.windows.inventory.FurnaceInventoryWindow +import ru.deadsoftware.cavedroid.misc.Assets +import ru.deadsoftware.cavedroid.misc.utils.drawSprite +import ru.deadsoftware.cavedroid.misc.utils.withScissors +import javax.inject.Inject + +@GameScope +class FurnaceWindowRenderer @Inject constructor( + private val mainConfig: MainConfig, + private val mobsController: MobsController, + private val gameWindowsManager: GameWindowsManager, + private val gameItemsHolder: GameItemsHolder, +) : AbstractWindowRenderer(), IGameRenderer { + + override val renderLayer get() = WindowsRenderer.RENDER_LAYER + + private val furnaceWindowTexture get() = requireNotNull(Assets.textureRegions[FURNACE_WINDOW_KEY]) + + + override fun draw(spriteBatch: SpriteBatch, shapeRenderer: ShapeRenderer, viewport: Rectangle, delta: Float) { + val windowTexture = furnaceWindowTexture + + val window = gameWindowsManager.currentWindow as FurnaceInventoryWindow + + val windowX = viewport.width / 2 - windowTexture.regionWidth / 2 + val windowY = viewport.height / 2 - windowTexture.regionHeight / 2 + + spriteBatch.draw(windowTexture, windowX, windowY) + drawItemsGrid( + spriteBatch = spriteBatch, + shapeRenderer = shapeRenderer, + gridX = windowX + GameWindowsConfigs.Furnace.itemsGridMarginLeft, + gridY = windowY + GameWindowsConfigs.Furnace.itemsGridMarginTop, + items = mobsController.player.inventory.items.asSequence() + .drop(GameWindowsConfigs.Furnace.hotbarCells) + .take(GameWindowsConfigs.Furnace.itemsInCol * GameWindowsConfigs.Furnace.itemsInRow) + .asIterable(), + itemsInRow = GameWindowsConfigs.Furnace.itemsInRow, + cellWidth = GameWindowsConfigs.Furnace.itemsGridColWidth, + cellHeight = GameWindowsConfigs.Furnace.itemsGridRowHeight, + ) + + drawItemsGrid( + spriteBatch = spriteBatch, + shapeRenderer = shapeRenderer, + gridX = windowX + GameWindowsConfigs.Furnace.itemsGridMarginLeft, + gridY = windowY + windowTexture.regionHeight - GameWindowsConfigs.Furnace.hotbarOffsetFromBottom, + items = mobsController.player.inventory.items.asSequence() + .take(GameWindowsConfigs.Furnace.hotbarCells) + .asIterable(), + itemsInRow = GameWindowsConfigs.Furnace.hotbarCells, + cellWidth = GameWindowsConfigs.Furnace.itemsGridColWidth, + cellHeight = GameWindowsConfigs.Furnace.itemsGridRowHeight, + ) + + window.furnace.fuel?.draw( + spriteBatch = spriteBatch, + shapeRenderer = shapeRenderer, + x = windowX + GameWindowsConfigs.Furnace.smeltFuelMarginLeft, + y = windowY + GameWindowsConfigs.Furnace.smeltFuelMarginTop + ) + + window.furnace.input?.draw( + spriteBatch = spriteBatch, + shapeRenderer = shapeRenderer, + x = windowX + GameWindowsConfigs.Furnace.smeltInputMarginLeft, + y = windowY + GameWindowsConfigs.Furnace.smeltInputMarginTop + ) + + window.furnace.result?.draw( + spriteBatch = spriteBatch, + shapeRenderer = shapeRenderer, + x = windowX + GameWindowsConfigs.Furnace.smeltResultOffsetX, + y = windowY + GameWindowsConfigs.Furnace.smeltResultOffsetY + ) + + if (window.furnace.isActive) { + val burn = GameWindowsConfigs.Furnace.fuelBurnHeight * window.furnace.burnProgress + + spriteBatch.withScissors( + mainConfig = mainConfig, + x = windowX + GameWindowsConfigs.Furnace.fuelBurnMarginLeft, + y = windowY + GameWindowsConfigs.Furnace.fuelBurnMarginTop + burn, + width = Assets.furnaceBurn.width, + height = GameWindowsConfigs.Furnace.fuelBurnHeight, + ) { + spriteBatch.drawSprite( + sprite = Assets.furnaceBurn, + x = windowX + GameWindowsConfigs.Furnace.fuelBurnMarginLeft, + y = windowY + GameWindowsConfigs.Furnace.fuelBurnMarginTop + ) + } + + if (window.furnace.canSmelt()) { + val progress = GameWindowsConfigs.Furnace.progressWidth * window.furnace.smeltProgress + + spriteBatch.withScissors( + mainConfig = mainConfig, + x = windowX + GameWindowsConfigs.Furnace.progressMarginLeft, + y = windowY + GameWindowsConfigs.Furnace.progressMarginTop, + width = progress, + height = Assets.furnaceProgress.height + ) { + spriteBatch.drawSprite( + sprite = Assets.furnaceProgress, + x = windowX + GameWindowsConfigs.Furnace.progressMarginLeft, + y = windowY + GameWindowsConfigs.Furnace.progressMarginTop, + ) + } + } + } + + window.selectedItem?.drawSelected( + spriteBatch = spriteBatch, + x = Gdx.input.x * (viewport.width / Gdx.graphics.width), + y = Gdx.input.y * (viewport.height / Gdx.graphics.height) + ) + } + + companion object { + private const val FURNACE_WINDOW_KEY = "furnace" + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsConfigs.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsConfigs.kt index 8fa3fb2..faef993 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsConfigs.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsConfigs.kt @@ -70,4 +70,35 @@ object GameWindowsConfigs { const val craftResultOffsetX = 128f const val craftResultOffsetY = 36f } + + data object Furnace { + const val itemsGridMarginLeft = 8f + const val itemsGridMarginTop = 84f + + const val itemsGridRowHeight = 18f + const val itemsGridColWidth = 18f + + const val itemsInRow = 9 + const val itemsInCol = 5 + + const val hotbarOffsetFromBottom = 24f + const val hotbarCells = 9 + + const val smeltInputMarginLeft = 56f + const val smeltInputMarginTop = 18f + + const val smeltFuelMarginLeft = 56f + const val smeltFuelMarginTop = 54f + + const val smeltResultOffsetX = 128f + const val smeltResultOffsetY = 36f + + const val fuelBurnMarginLeft = 56f + const val fuelBurnMarginTop = 36f + const val fuelBurnHeight = 14f + + const val progressMarginLeft = 79f + const val progressMarginTop = 34f + const val progressWidth = 24f + } } \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsManager.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsManager.kt index 05c8a9b..1b6611a 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsManager.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsManager.kt @@ -3,12 +3,10 @@ package ru.deadsoftware.cavedroid.game.ui.windows import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.mobs.MobsController -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.DropController +import ru.deadsoftware.cavedroid.game.objects.furnace.Furnace import ru.deadsoftware.cavedroid.game.ui.TooltipManager -import ru.deadsoftware.cavedroid.game.ui.windows.inventory.AbstractInventoryWindow -import ru.deadsoftware.cavedroid.game.ui.windows.inventory.CraftingInventoryWindow -import ru.deadsoftware.cavedroid.game.ui.windows.inventory.CreativeInventoryWindow -import ru.deadsoftware.cavedroid.game.ui.windows.inventory.SurvivalInventoryWindow +import ru.deadsoftware.cavedroid.game.ui.windows.inventory.* import javax.inject.Inject @GameScope @@ -36,6 +34,10 @@ class GameWindowsManager @Inject constructor( } } + fun openFurnace(furnace: Furnace) { + currentWindow = FurnaceInventoryWindow(furnace) + } + fun openCrafting() { currentWindow = CraftingInventoryWindow() } diff --git a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/FurnaceInventoryWindow.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/FurnaceInventoryWindow.kt new file mode 100644 index 0000000..5adaac6 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/FurnaceInventoryWindow.kt @@ -0,0 +1,15 @@ +package ru.deadsoftware.cavedroid.game.ui.windows.inventory + +import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem +import ru.deadsoftware.cavedroid.game.objects.furnace.Furnace + +class FurnaceInventoryWindow( + val furnace: Furnace, +) : AbstractInventoryWindow() { + + override val type = GameUiWindow.FURNACE + + override var selectedItem: InventoryItem? = null + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/world/GameWorld.java b/core/src/ru/deadsoftware/cavedroid/game/world/GameWorld.java index 686f1c9..0d5a80a 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/world/GameWorld.java +++ b/core/src/ru/deadsoftware/cavedroid/game/world/GameWorld.java @@ -8,7 +8,9 @@ import ru.deadsoftware.cavedroid.game.model.block.Block; import ru.deadsoftware.cavedroid.game.model.item.InventoryItem; import ru.deadsoftware.cavedroid.game.model.item.Item; import ru.deadsoftware.cavedroid.game.model.world.generator.WorldGeneratorConfig; -import ru.deadsoftware.cavedroid.game.objects.DropController; +import ru.deadsoftware.cavedroid.game.objects.drop.DropController; +import ru.deadsoftware.cavedroid.game.objects.furnace.Furnace; +import ru.deadsoftware.cavedroid.game.objects.furnace.FurnaceController; import ru.deadsoftware.cavedroid.misc.utils.MeasureUnitsUtilsKt; import javax.annotation.CheckForNull; @@ -20,6 +22,7 @@ public class GameWorld { private final DropController mDropController; private final MobsController mMobsController; private final GameItemsHolder mGameItemsHolder; + private final FurnaceController mFurnaceController; private final int mWidth; private final int mHeight; @@ -32,11 +35,13 @@ public class GameWorld { public GameWorld(DropController dropController, MobsController mobsController, GameItemsHolder gameItemsHolder, + FurnaceController furnaceController, @CheckForNull Block[][] foreMap, @CheckForNull Block[][] backMap) { mDropController = dropController; mMobsController = mobsController; mGameItemsHolder = gameItemsHolder; + mFurnaceController = furnaceController; boolean isNewGame = foreMap == null || backMap == null; @@ -170,6 +175,11 @@ public class GameWorld { public boolean placeToForeground(int x, int y, Block value) { if (!hasForeAt(x, y) || value == mGameItemsHolder.getFallbackBlock() || !getForeMap(x, y).hasCollision()) { + + if (value.isFurnace()) { + mFurnaceController.addFurnace(x, y, 0); + } + setForeMap(x, y, value); return true; } else if (value instanceof Block.Slab && isSameSlab(value, getForeMap(x, y))) { @@ -182,6 +192,9 @@ public class GameWorld { public boolean placeToBackground(int x, int y, Block value) { if (value == mGameItemsHolder.getFallbackBlock() || (getBackMap(x, y) == mGameItemsHolder.getFallbackBlock() && value.hasCollision()) && (!value.isTransparent() || value == mGameItemsHolder.getBlock("glass"))) { + if (value.isFurnace()) { + mFurnaceController.addFurnace(x, y, 1); + } setBackMap(x, y, value); return true; } @@ -206,6 +219,9 @@ public class GameWorld { public void destroyForeMap(int x, int y) { Block block = getForeMap(x, y); + if (block.isFurnace()) { + mFurnaceController.destroyFurnace(x, y, 0, mDropController); + } if (block.hasDrop() && shouldDrop(block)) { for (int i = 0; i < block.getParams().getDropInfo().getCount(); i++) { mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, mGameItemsHolder.getItem(block.getDrop())); @@ -221,6 +237,9 @@ public class GameWorld { public void destroyBackMap(int x, int y) { Block block = getBackMap(x, y); + if (block.isFurnace()) { + mFurnaceController.destroyFurnace(x, y, 0, mDropController); + } if (block.hasDrop() && shouldDrop(block)) { for (int i = 0; i < block.getParams().getDropInfo().getCount(); i++) { mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, mGameItemsHolder.getItem(block.getDrop())); @@ -229,4 +248,14 @@ public class GameWorld { playerDurateTool(); placeToBackground(x, y, mGameItemsHolder.getFallbackBlock()); } + + @CheckForNull + public Furnace getForegroundFurnace(int x, int y) { + return mFurnaceController.getFurnace(x, y, 0); + } + + @CheckForNull + public Furnace getBackgroundFurnace(int x, int y) { + return mFurnaceController.getFurnace(x, y, 1); + } } \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/misc/Assets.java b/core/src/ru/deadsoftware/cavedroid/misc/Assets.java index 329207f..ffc253f 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/Assets.java +++ b/core/src/ru/deadsoftware/cavedroid/misc/Assets.java @@ -44,6 +44,9 @@ public class Assets { public static Sprite joyBackground; public static Sprite joyStick; + public static Sprite furnaceBurn; + public static Sprite furnaceProgress; + public static void dispose() { minecraftFont.dispose(); loadedTextures.forEach(Texture::dispose); @@ -196,6 +199,11 @@ public class Assets { joyBackground = new Sprite(loadTexture(assetLoader.getAssetHandle("joy_background.png"))); } + private static void loadFurnace(AssetLoader assetLoader) { + furnaceBurn = new Sprite(textureRegions.get("furnace_burn")); + furnaceProgress = new Sprite(textureRegions.get("furnace_progress")); + } + public static void load(final AssetLoader assetLoader) { loadMob(assetLoader, playerSprite, "char"); loadMob(assetLoader, pigSprite, "pig"); @@ -205,6 +213,7 @@ public class Assets { loadItems(assetLoader); loadTouchButtonsFromJSON(assetLoader); loadJoystick(assetLoader); + loadFurnace(assetLoader); setPlayerHeadOrigin(); minecraftFont = new BitmapFont(assetLoader.getAssetHandle("font.fnt"), true); minecraftFont.getData().setScale(.375f); diff --git a/core/src/ru/deadsoftware/cavedroid/misc/utils/MeasureUnitsUtils.kt b/core/src/ru/deadsoftware/cavedroid/misc/utils/MeasureUnitsUtils.kt index ecf1ce0..24103e7 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/utils/MeasureUnitsUtils.kt +++ b/core/src/ru/deadsoftware/cavedroid/misc/utils/MeasureUnitsUtils.kt @@ -15,4 +15,4 @@ val Int.px get() = this * 16f /** * Converts this value in PIXELS into blocks */ -val Float.bl get() = MathUtils.floor(this / 16) \ No newline at end of file +val Float.bl get() = MathUtils.floor(this / 16f) \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/misc/utils/RenderingUtils.kt b/core/src/ru/deadsoftware/cavedroid/misc/utils/RenderingUtils.kt index 8976c99..917f69b 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/utils/RenderingUtils.kt +++ b/core/src/ru/deadsoftware/cavedroid/misc/utils/RenderingUtils.kt @@ -1,9 +1,12 @@ package ru.deadsoftware.cavedroid.misc.utils +import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.graphics.GL20 import com.badlogic.gdx.graphics.g2d.GlyphLayout import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.math.Rectangle +import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.misc.Assets private fun Rectangle.shifted(shift: Float) = Rectangle(x + shift, y, width, height) @@ -69,3 +72,27 @@ fun colorFromHexString(hex: String): Color { rgba = (rgba shl 8) or 0xFF return Color(rgba) } + +fun SpriteBatch.withScissors( + mainConfig: MainConfig, + x: Float, + y: Float, + width: Float, + height: Float, + block: () -> Unit +) { + val scaleX = Gdx.graphics.width / mainConfig.width + val scaleY = Gdx.graphics.height / mainConfig.height + + flush() + Gdx.gl.glEnable(GL20.GL_SCISSOR_TEST) + Gdx.gl.glScissor( + /* x = */ (x * scaleX).toInt(), + /* y = */ ((mainConfig.height - y - height) * scaleY).toInt(), + /* width = */ (width * scaleX).toInt(), + /* height = */ (height * scaleY).toInt() + ) + block.invoke() + flush() + Gdx.gl.glDisable(GL20.GL_SCISSOR_TEST) +}