From c6cc5faba2c3585088224878508dd75052f7291f Mon Sep 17 00:00:00 2001 From: jzitnik-dev Date: Wed, 24 Sep 2025 12:27:17 +0200 Subject: [PATCH] feat: Idk --- src/main/java/cz/jzitnik/game/Game.java | 6 +- .../jzitnik/game/annotations/FireImmune.java | 12 ++++ .../game/annotations/LightBurningMob.java | 12 ++++ .../entities/items/registry/mobs/Zombie.java | 2 + .../jzitnik/game/generation/Generation.java | 2 + .../burning/LightBurningMobLogic.java | 71 +++++++++++++++++++ .../logic/services/burning/MobsBurning.java | 4 ++ .../firespreading/FireSpreadingLogic.java | 2 +- .../logic/services/flowing/LavaFireLogic.java | 45 ++++++++++-- .../services/zombie/ZombieSpawnLogic.java | 4 ++ .../game/threads/list/InputHandlerThread.java | 10 +-- .../java/cz/jzitnik/tui/ScreenRenderer.java | 2 +- 12 files changed, 157 insertions(+), 15 deletions(-) create mode 100644 src/main/java/cz/jzitnik/game/annotations/FireImmune.java create mode 100644 src/main/java/cz/jzitnik/game/annotations/LightBurningMob.java create mode 100644 src/main/java/cz/jzitnik/game/logic/services/burning/LightBurningMobLogic.java create mode 100644 src/main/java/cz/jzitnik/game/logic/services/burning/MobsBurning.java diff --git a/src/main/java/cz/jzitnik/game/Game.java b/src/main/java/cz/jzitnik/game/Game.java index bcec83c..2d1b9ac 100644 --- a/src/main/java/cz/jzitnik/game/Game.java +++ b/src/main/java/cz/jzitnik/game/Game.java @@ -73,6 +73,10 @@ public class Game { Generation.generateWorld(this); } + public boolean isNight(){ + return daytime > 200 && daytime < 400; + } + /** * Returns the current coordinates of the player (bottom half). * @@ -617,7 +621,7 @@ public class Game { * @return true if any block is not a ghost block. */ public boolean isSolid(List blocks) { - return !blocks.stream().allMatch(Block::isGhost); + return !blocks.stream().allMatch(block -> block.isGhost() || block.isMob()); } /** diff --git a/src/main/java/cz/jzitnik/game/annotations/FireImmune.java b/src/main/java/cz/jzitnik/game/annotations/FireImmune.java new file mode 100644 index 0000000..a500209 --- /dev/null +++ b/src/main/java/cz/jzitnik/game/annotations/FireImmune.java @@ -0,0 +1,12 @@ +package cz.jzitnik.game.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@RequireAnnotation(BlockRegistry.class) +public @interface FireImmune { +} diff --git a/src/main/java/cz/jzitnik/game/annotations/LightBurningMob.java b/src/main/java/cz/jzitnik/game/annotations/LightBurningMob.java new file mode 100644 index 0000000..e97ab91 --- /dev/null +++ b/src/main/java/cz/jzitnik/game/annotations/LightBurningMob.java @@ -0,0 +1,12 @@ +package cz.jzitnik.game.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@RequireAnnotation(BlockRegistry.class) +public @interface LightBurningMob { +} diff --git a/src/main/java/cz/jzitnik/game/entities/items/registry/mobs/Zombie.java b/src/main/java/cz/jzitnik/game/entities/items/registry/mobs/Zombie.java index c292e66..d71e8e3 100644 --- a/src/main/java/cz/jzitnik/game/entities/items/registry/mobs/Zombie.java +++ b/src/main/java/cz/jzitnik/game/entities/items/registry/mobs/Zombie.java @@ -3,10 +3,12 @@ package cz.jzitnik.game.entities.items.registry.mobs; import cz.jzitnik.game.SpriteLoader; import cz.jzitnik.game.annotations.CustomMobFallingAfterMineLogic; import cz.jzitnik.game.annotations.EntityRegistry; +import cz.jzitnik.game.annotations.LightBurningMob; import cz.jzitnik.game.entities.Block; import cz.jzitnik.game.mobs.services.zombie.ZombieData; import cz.jzitnik.game.mobs.services.zombie.ZombieFallingAfterMineLogic; +@LightBurningMob @CustomMobFallingAfterMineLogic(ZombieFallingAfterMineLogic.class) @EntityRegistry("zombie") public class Zombie extends Block { diff --git a/src/main/java/cz/jzitnik/game/generation/Generation.java b/src/main/java/cz/jzitnik/game/generation/Generation.java index b3d7ad2..2886d7b 100644 --- a/src/main/java/cz/jzitnik/game/generation/Generation.java +++ b/src/main/java/cz/jzitnik/game/generation/Generation.java @@ -27,6 +27,8 @@ public class Generation { int[] terrainHeight = PopulateWorld.generateTerrain(); + game.getInventory().addItem(ItemBlockSupplier.getItem("lava_bucket")); + game.getPlayer().setPlayerBlock1(steveBlock); game.getPlayer().setPlayerBlock2(steveBlock2); diff --git a/src/main/java/cz/jzitnik/game/logic/services/burning/LightBurningMobLogic.java b/src/main/java/cz/jzitnik/game/logic/services/burning/LightBurningMobLogic.java new file mode 100644 index 0000000..60f2239 --- /dev/null +++ b/src/main/java/cz/jzitnik/game/logic/services/burning/LightBurningMobLogic.java @@ -0,0 +1,71 @@ +package cz.jzitnik.game.logic.services.burning; + +import cz.jzitnik.game.Game; +import cz.jzitnik.game.annotations.CustomLogic; +import cz.jzitnik.game.annotations.LightBurningMob; +import cz.jzitnik.game.entities.Block; +import cz.jzitnik.game.entities.items.Item; +import cz.jzitnik.game.logic.CustomLogicInterface; +import cz.jzitnik.tui.ScreenRenderer; + +@CustomLogic +public class LightBurningMobLogic implements CustomLogicInterface { + private static final int RADIUS = 30; + + @Override + public void nextIteration(Game game, ScreenRenderer screenRenderer) { + if (!game.isNight()) { + return; + } + + int[] data = game.getPlayerCords(); + var world = game.getWorld(); + int playerX = data[0]; + int playerY = data[1]; + + int startX = Math.max(0, playerX - RADIUS); + int startY = Math.max(0, playerY - RADIUS); + int endX = Math.min(world[0].length - 1, playerX + RADIUS); + int endY = Math.min(world.length - 1, playerY + RADIUS); + + for (int y = startY; y <= endY; y++) { + for (int x = startX; x <= endX; x++) { + var blocks = world[y][x]; + + for (Block block : blocks) { + if (block.getClass().isAnnotationPresent(LightBurningMob.class)) { + int dealDamage = game.getInventory().getItemInHand().map(Item::getDealDamage).orElse(1); + if (block.getHp() - dealDamage <= 0) { + // Mob is killed + world[y][x].remove(block); + } else { + block.decreaseHp(dealDamage); + block.setSpriteState(game.getGameStates().dependencies.entityHurtAnimation.get(block.getBlockId()) + .setHurtAnimation(true, block.getSpriteState().get())); + if (block.getLinkedMobTexture() != null) { + block.getLinkedMobTexture().setSpriteState(game.getGameStates().dependencies.entityHurtAnimation.get(block.getBlockId()) + .setHurtAnimation(true, block.getLinkedMobTexture().getSpriteState().get())); + } + } + + new Thread(() -> { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + block.setSpriteState(game.getGameStates().dependencies.entityHurtAnimation.get(block.getBlockId()) + .setHurtAnimation(false, block.getSpriteState().get())); + + if (block.getLinkedMobTexture() != null) { + block.getLinkedMobTexture().setSpriteState(game.getGameStates().dependencies.entityHurtAnimation.get(block.getBlockId()) + .setHurtAnimation(false, block.getLinkedMobTexture().getSpriteState().get())); + } + }).start(); + } + } + } + } + } +} diff --git a/src/main/java/cz/jzitnik/game/logic/services/burning/MobsBurning.java b/src/main/java/cz/jzitnik/game/logic/services/burning/MobsBurning.java new file mode 100644 index 0000000..3d6a44b --- /dev/null +++ b/src/main/java/cz/jzitnik/game/logic/services/burning/MobsBurning.java @@ -0,0 +1,4 @@ +package cz.jzitnik.game.logic.services.burning; + +public class MobsBurning { +} diff --git a/src/main/java/cz/jzitnik/game/logic/services/firespreading/FireSpreadingLogic.java b/src/main/java/cz/jzitnik/game/logic/services/firespreading/FireSpreadingLogic.java index 39f01d2..1eb5441 100644 --- a/src/main/java/cz/jzitnik/game/logic/services/firespreading/FireSpreadingLogic.java +++ b/src/main/java/cz/jzitnik/game/logic/services/firespreading/FireSpreadingLogic.java @@ -32,7 +32,7 @@ public class FireSpreadingLogic implements CustomLogicInterface { var blocks = world[y][x]; for (Block block : blocks) { - if (block.isOnFire() && block.getClass().getAnnotation(Flamable.class).value()) { + if ((block.isOnFire() && !block.isMob()) && block.getClass().getAnnotation(Flamable.class).value()) { int maxTime = random.nextInt(30) + 15; block.setBurningTime2(block.getBurningTime2() + 1); if (block.getBurningTime2() >= maxTime) { diff --git a/src/main/java/cz/jzitnik/game/logic/services/flowing/LavaFireLogic.java b/src/main/java/cz/jzitnik/game/logic/services/flowing/LavaFireLogic.java index 8c57fb0..67ac0f1 100644 --- a/src/main/java/cz/jzitnik/game/logic/services/flowing/LavaFireLogic.java +++ b/src/main/java/cz/jzitnik/game/logic/services/flowing/LavaFireLogic.java @@ -4,8 +4,10 @@ import java.util.Random; import cz.jzitnik.game.Game; import cz.jzitnik.game.annotations.CustomLogic; +import cz.jzitnik.game.annotations.FireImmune; import cz.jzitnik.game.annotations.Flamable; import cz.jzitnik.game.entities.Block; +import cz.jzitnik.game.entities.items.Item; import cz.jzitnik.game.logic.CustomLogicInterface; import cz.jzitnik.tui.ScreenRenderer; @@ -48,12 +50,45 @@ public class LavaFireLogic implements CustomLogicInterface { } for (Block block : world[y][x]) { - if (block.getClass().isAnnotationPresent(Flamable.class) && !block.isOnFire()) { + if ((block.getClass().isAnnotationPresent(Flamable.class) || block.isMob()) && !block.isOnFire()) { int maxTime = random.nextInt(8) + 5; - block.setBurningTime(block.getBurningTime() + 1); - if (block.getBurningTime() >= maxTime) { - block.setOnFire(true); - block.setBurningTime(0); + + if (!block.isMob()) { + block.setBurningTime(block.getBurningTime() + 1); + if (block.getBurningTime() >= maxTime) { + block.setOnFire(true); + block.setBurningTime(0); + } + } else if (!block.getClass().isAnnotationPresent(FireImmune.class)) { + int dealDamage = game.getInventory().getItemInHand().map(Item::getDealDamage).orElse(1); + if (block.getHp() - dealDamage <= 0) { + // Mob is killed + world[y][x].remove(block); + } else { + block.decreaseHp(dealDamage); + block.setSpriteState(game.getGameStates().dependencies.entityHurtAnimation.get(block.getBlockId()) + .setHurtAnimation(true, block.getSpriteState().get())); + if (block.getLinkedMobTexture() != null) { + block.getLinkedMobTexture().setSpriteState(game.getGameStates().dependencies.entityHurtAnimation.get(block.getBlockId()) + .setHurtAnimation(true, block.getLinkedMobTexture().getSpriteState().get())); + } + } + + new Thread(() -> { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + block.setSpriteState(game.getGameStates().dependencies.entityHurtAnimation.get(block.getBlockId()) + .setHurtAnimation(false, block.getSpriteState().get())); + + if (block.getLinkedMobTexture() != null) { + block.getLinkedMobTexture().setSpriteState(game.getGameStates().dependencies.entityHurtAnimation.get(block.getBlockId()) + .setHurtAnimation(false, block.getLinkedMobTexture().getSpriteState().get())); + } + }).start(); } } } diff --git a/src/main/java/cz/jzitnik/game/mobs/services/zombie/ZombieSpawnLogic.java b/src/main/java/cz/jzitnik/game/mobs/services/zombie/ZombieSpawnLogic.java index 3a17c5f..f650f69 100644 --- a/src/main/java/cz/jzitnik/game/mobs/services/zombie/ZombieSpawnLogic.java +++ b/src/main/java/cz/jzitnik/game/mobs/services/zombie/ZombieSpawnLogic.java @@ -16,6 +16,10 @@ public class ZombieSpawnLogic implements EntitySpawnInterface { @Override public void spawn(int playerX, int playerY, Game game, Terminal terminal) { + if (!game.isNight()) { + return; + } + int[] view = ScreenMovingCalculationProvider.calculate(playerX, playerY, terminal.getHeight(), terminal.getWidth(), game.getWorld()[0].length, game.getWorld().length); int startX = view[0]; int endX = view[1]; diff --git a/src/main/java/cz/jzitnik/game/threads/list/InputHandlerThread.java b/src/main/java/cz/jzitnik/game/threads/list/InputHandlerThread.java index a7b10a4..bb8f28b 100644 --- a/src/main/java/cz/jzitnik/game/threads/list/InputHandlerThread.java +++ b/src/main/java/cz/jzitnik/game/threads/list/InputHandlerThread.java @@ -84,13 +84,9 @@ public class InputHandlerThread extends Thread { switch (key) { case '1', '2', '3', '4', '5', '6', '7', '8', '9' -> game.changeSlot(key - 49, screenRenderer); - case 'a' -> { - game.movePlayerLeft(screenRenderer, terminal); - } - case 'd' -> { - game.movePlayerRight(screenRenderer, terminal); - } - case ' ' -> { + case 'a' -> new Thread(() -> game.movePlayerLeft(screenRenderer, terminal)).start(); + case 'd' -> new Thread(() -> game.movePlayerRight(screenRenderer, terminal)).start(); + case ' ' ->{ game.movePlayerUp(screenRenderer); screenRenderer.render(game); } diff --git a/src/main/java/cz/jzitnik/tui/ScreenRenderer.java b/src/main/java/cz/jzitnik/tui/ScreenRenderer.java index e161da3..818dd24 100644 --- a/src/main/java/cz/jzitnik/tui/ScreenRenderer.java +++ b/src/main/java/cz/jzitnik/tui/ScreenRenderer.java @@ -99,7 +99,7 @@ public class ScreenRenderer { * * @param game Current game state to render. */ - public synchronized void render(Game game) { + public void render(Game game) { if (rendering) { return; }