feat: Idk

This commit is contained in:
2025-09-24 12:27:17 +02:00
parent bfafe8577a
commit c6cc5faba2
12 changed files with 157 additions and 15 deletions

View File

@ -73,6 +73,10 @@ public class Game {
Generation.generateWorld(this); Generation.generateWorld(this);
} }
public boolean isNight(){
return daytime > 200 && daytime < 400;
}
/** /**
* Returns the current coordinates of the player (bottom half). * 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. * @return true if any block is not a ghost block.
*/ */
public boolean isSolid(List<Block> blocks) { public boolean isSolid(List<Block> blocks) {
return !blocks.stream().allMatch(Block::isGhost); return !blocks.stream().allMatch(block -> block.isGhost() || block.isMob());
} }
/** /**

View File

@ -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 {
}

View File

@ -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 {
}

View File

@ -3,10 +3,12 @@ package cz.jzitnik.game.entities.items.registry.mobs;
import cz.jzitnik.game.SpriteLoader; import cz.jzitnik.game.SpriteLoader;
import cz.jzitnik.game.annotations.CustomMobFallingAfterMineLogic; import cz.jzitnik.game.annotations.CustomMobFallingAfterMineLogic;
import cz.jzitnik.game.annotations.EntityRegistry; import cz.jzitnik.game.annotations.EntityRegistry;
import cz.jzitnik.game.annotations.LightBurningMob;
import cz.jzitnik.game.entities.Block; import cz.jzitnik.game.entities.Block;
import cz.jzitnik.game.mobs.services.zombie.ZombieData; import cz.jzitnik.game.mobs.services.zombie.ZombieData;
import cz.jzitnik.game.mobs.services.zombie.ZombieFallingAfterMineLogic; import cz.jzitnik.game.mobs.services.zombie.ZombieFallingAfterMineLogic;
@LightBurningMob
@CustomMobFallingAfterMineLogic(ZombieFallingAfterMineLogic.class) @CustomMobFallingAfterMineLogic(ZombieFallingAfterMineLogic.class)
@EntityRegistry("zombie") @EntityRegistry("zombie")
public class Zombie extends Block { public class Zombie extends Block {

View File

@ -27,6 +27,8 @@ public class Generation {
int[] terrainHeight = PopulateWorld.generateTerrain(); int[] terrainHeight = PopulateWorld.generateTerrain();
game.getInventory().addItem(ItemBlockSupplier.getItem("lava_bucket"));
game.getPlayer().setPlayerBlock1(steveBlock); game.getPlayer().setPlayerBlock1(steveBlock);
game.getPlayer().setPlayerBlock2(steveBlock2); game.getPlayer().setPlayerBlock2(steveBlock2);

View File

@ -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();
}
}
}
}
}
}

View File

@ -0,0 +1,4 @@
package cz.jzitnik.game.logic.services.burning;
public class MobsBurning {
}

View File

@ -32,7 +32,7 @@ public class FireSpreadingLogic implements CustomLogicInterface {
var blocks = world[y][x]; var blocks = world[y][x];
for (Block block : blocks) { 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; int maxTime = random.nextInt(30) + 15;
block.setBurningTime2(block.getBurningTime2() + 1); block.setBurningTime2(block.getBurningTime2() + 1);
if (block.getBurningTime2() >= maxTime) { if (block.getBurningTime2() >= maxTime) {

View File

@ -4,8 +4,10 @@ import java.util.Random;
import cz.jzitnik.game.Game; import cz.jzitnik.game.Game;
import cz.jzitnik.game.annotations.CustomLogic; import cz.jzitnik.game.annotations.CustomLogic;
import cz.jzitnik.game.annotations.FireImmune;
import cz.jzitnik.game.annotations.Flamable; import cz.jzitnik.game.annotations.Flamable;
import cz.jzitnik.game.entities.Block; import cz.jzitnik.game.entities.Block;
import cz.jzitnik.game.entities.items.Item;
import cz.jzitnik.game.logic.CustomLogicInterface; import cz.jzitnik.game.logic.CustomLogicInterface;
import cz.jzitnik.tui.ScreenRenderer; import cz.jzitnik.tui.ScreenRenderer;
@ -48,13 +50,46 @@ public class LavaFireLogic implements CustomLogicInterface {
} }
for (Block block : world[y][x]) { 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; int maxTime = random.nextInt(8) + 5;
if (!block.isMob()) {
block.setBurningTime(block.getBurningTime() + 1); block.setBurningTime(block.getBurningTime() + 1);
if (block.getBurningTime() >= maxTime) { if (block.getBurningTime() >= maxTime) {
block.setOnFire(true); block.setOnFire(true);
block.setBurningTime(0); 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();
}
} }
} }
} }

View File

@ -16,6 +16,10 @@ public class ZombieSpawnLogic implements EntitySpawnInterface {
@Override @Override
public void spawn(int playerX, int playerY, Game game, Terminal terminal) { 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[] view = ScreenMovingCalculationProvider.calculate(playerX, playerY, terminal.getHeight(), terminal.getWidth(), game.getWorld()[0].length, game.getWorld().length);
int startX = view[0]; int startX = view[0];
int endX = view[1]; int endX = view[1];

View File

@ -84,12 +84,8 @@ public class InputHandlerThread extends Thread {
switch (key) { switch (key) {
case '1', '2', '3', '4', '5', '6', '7', '8', '9' -> game.changeSlot(key - 49, screenRenderer); case '1', '2', '3', '4', '5', '6', '7', '8', '9' -> game.changeSlot(key - 49, screenRenderer);
case 'a' -> { case 'a' -> new Thread(() -> game.movePlayerLeft(screenRenderer, terminal)).start();
game.movePlayerLeft(screenRenderer, terminal); case 'd' -> new Thread(() -> game.movePlayerRight(screenRenderer, terminal)).start();
}
case 'd' -> {
game.movePlayerRight(screenRenderer, terminal);
}
case ' ' ->{ case ' ' ->{
game.movePlayerUp(screenRenderer); game.movePlayerUp(screenRenderer);
screenRenderer.render(game); screenRenderer.render(game);

View File

@ -99,7 +99,7 @@ public class ScreenRenderer {
* *
* @param game Current game state to render. * @param game Current game state to render.
*/ */
public synchronized void render(Game game) { public void render(Game game) {
if (rendering) { if (rendering) {
return; return;
} }