forked from jzitnik/twodcraft
feat: Implemented block burning spreading
This commit is contained in:
parent
36e57bbb8d
commit
8b8c23dad4
@ -17,13 +17,14 @@ public class Main {
|
|||||||
try {
|
try {
|
||||||
Terminal terminal = TerminalBuilder.terminal();
|
Terminal terminal = TerminalBuilder.terminal();
|
||||||
terminal.enterRawMode();
|
terminal.enterRawMode();
|
||||||
terminal.trackMouse(Terminal.MouseTracking.Any);
|
|
||||||
|
|
||||||
if (!terminal.hasMouseSupport()) {
|
if (!terminal.hasMouseSupport()) {
|
||||||
System.out.println("Error: This terminal does not support mouse.");
|
System.out.println("Error: This terminal does not support mouse.");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
terminal.trackMouse(Terminal.MouseTracking.Any);
|
||||||
|
|
||||||
var spriteList = SpriteLoader.load();
|
var spriteList = SpriteLoader.load();
|
||||||
var screenRenderer = new ScreenRenderer(spriteList, terminal);
|
var screenRenderer = new ScreenRenderer(spriteList, terminal);
|
||||||
var game = GameSaver.load();
|
var game = GameSaver.load();
|
||||||
|
@ -219,6 +219,11 @@ public class Game extends AutoTransientSupport {
|
|||||||
.get(blocks.stream().filter(Block::isMineable).toList().getFirst().getBlockId());
|
.get(blocks.stream().filter(Block::isMineable).toList().getFirst().getBlockId());
|
||||||
boolean giveItem = customPlaceHandler.mine(this, x, y);
|
boolean giveItem = customPlaceHandler.mine(this, x, y);
|
||||||
|
|
||||||
|
blocksCopy.forEach((e) -> {
|
||||||
|
e.setOnFire(false);
|
||||||
|
e.setBurningTime(0);
|
||||||
|
});
|
||||||
|
|
||||||
if (giveItem) {
|
if (giveItem) {
|
||||||
for (Block block : blocksCopy) {
|
for (Block block : blocksCopy) {
|
||||||
if (!block.isMineable()) {
|
if (!block.isMineable()) {
|
||||||
@ -382,6 +387,12 @@ public class Game extends AutoTransientSupport {
|
|||||||
if (inventory.getItemInHand().isPresent()) {
|
if (inventory.getItemInHand().isPresent()) {
|
||||||
var item = inventory.getItemInHand().get();
|
var item = inventory.getItemInHand().get();
|
||||||
toolUsed = gameStates.dependencies.toolUseProvider.handle(item.getType(), this, x, y);
|
toolUsed = gameStates.dependencies.toolUseProvider.handle(item.getType(), this, x, y);
|
||||||
|
if (toolUsed) {
|
||||||
|
boolean broken = item.use();
|
||||||
|
if (broken) {
|
||||||
|
inventory.decreaseItemInHand();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!toolUsed) {
|
if (!toolUsed) {
|
||||||
|
@ -7,6 +7,7 @@ import java.lang.annotation.ElementType;
|
|||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
|
@RequireAnnotation(BlockRegistry.class)
|
||||||
public @interface Farmable {
|
public @interface Farmable {
|
||||||
String value();
|
String value();
|
||||||
}
|
}
|
||||||
|
12
src/main/java/cz/jzitnik/game/annotations/Flamable.java
Normal file
12
src/main/java/cz/jzitnik/game/annotations/Flamable.java
Normal 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 Flamable {
|
||||||
|
}
|
@ -28,6 +28,9 @@ public class Block implements Serializable {
|
|||||||
private boolean flowing = false;
|
private boolean flowing = false;
|
||||||
private boolean isMob = false;
|
private boolean isMob = false;
|
||||||
private int hp = 0;
|
private int hp = 0;
|
||||||
|
private boolean onFire = false;
|
||||||
|
private int burningTime = 0;
|
||||||
|
private int burningTime2 = 0;
|
||||||
|
|
||||||
public Block(String blockId, SpriteLoader.SPRITES sprite) {
|
public Block(String blockId, SpriteLoader.SPRITES sprite) {
|
||||||
this.blockId = blockId;
|
this.blockId = blockId;
|
||||||
|
@ -2,6 +2,7 @@ package cz.jzitnik.game.entities.items.registry.blocks.blocks;
|
|||||||
|
|
||||||
import cz.jzitnik.game.SpriteLoader;
|
import cz.jzitnik.game.SpriteLoader;
|
||||||
import cz.jzitnik.game.annotations.BlockRegistry;
|
import cz.jzitnik.game.annotations.BlockRegistry;
|
||||||
|
import cz.jzitnik.game.annotations.Flamable;
|
||||||
import cz.jzitnik.game.annotations.ReduceFallDamage;
|
import cz.jzitnik.game.annotations.ReduceFallDamage;
|
||||||
import cz.jzitnik.game.core.reducefalldamage.HaybaleFallDamageReducer;
|
import cz.jzitnik.game.core.reducefalldamage.HaybaleFallDamageReducer;
|
||||||
import cz.jzitnik.game.entities.Block;
|
import cz.jzitnik.game.entities.Block;
|
||||||
@ -9,6 +10,7 @@ import cz.jzitnik.game.entities.items.ItemType;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@Flamable
|
||||||
@BlockRegistry("haybale")
|
@BlockRegistry("haybale")
|
||||||
@ReduceFallDamage(HaybaleFallDamageReducer.class)
|
@ReduceFallDamage(HaybaleFallDamageReducer.class)
|
||||||
public class HaybaleBlock extends Block {
|
public class HaybaleBlock extends Block {
|
||||||
|
@ -2,6 +2,7 @@ package cz.jzitnik.game.entities.items.registry.blocks.blocks;
|
|||||||
|
|
||||||
import cz.jzitnik.game.SpriteLoader;
|
import cz.jzitnik.game.SpriteLoader;
|
||||||
import cz.jzitnik.game.annotations.BlockRegistry;
|
import cz.jzitnik.game.annotations.BlockRegistry;
|
||||||
|
import cz.jzitnik.game.annotations.Flamable;
|
||||||
import cz.jzitnik.game.annotations.PlaceOnSolidNoHandler;
|
import cz.jzitnik.game.annotations.PlaceOnSolidNoHandler;
|
||||||
import cz.jzitnik.game.blocks.OakDoorData;
|
import cz.jzitnik.game.blocks.OakDoorData;
|
||||||
import cz.jzitnik.game.entities.Block;
|
import cz.jzitnik.game.entities.Block;
|
||||||
@ -9,6 +10,7 @@ import cz.jzitnik.game.entities.items.ItemType;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@Flamable
|
||||||
@PlaceOnSolidNoHandler
|
@PlaceOnSolidNoHandler
|
||||||
@BlockRegistry("oak_door")
|
@BlockRegistry("oak_door")
|
||||||
public class OakDoorBlock extends Block {
|
public class OakDoorBlock extends Block {
|
||||||
|
@ -2,11 +2,13 @@ package cz.jzitnik.game.entities.items.registry.blocks.blocks;
|
|||||||
|
|
||||||
import cz.jzitnik.game.SpriteLoader;
|
import cz.jzitnik.game.SpriteLoader;
|
||||||
import cz.jzitnik.game.annotations.BlockRegistry;
|
import cz.jzitnik.game.annotations.BlockRegistry;
|
||||||
|
import cz.jzitnik.game.annotations.Flamable;
|
||||||
import cz.jzitnik.game.entities.Block;
|
import cz.jzitnik.game.entities.Block;
|
||||||
import cz.jzitnik.game.entities.items.ItemType;
|
import cz.jzitnik.game.entities.items.ItemType;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@Flamable
|
||||||
@BlockRegistry("oak_log")
|
@BlockRegistry("oak_log")
|
||||||
public class OakLogBlock extends Block {
|
public class OakLogBlock extends Block {
|
||||||
public OakLogBlock() {
|
public OakLogBlock() {
|
||||||
|
@ -2,11 +2,13 @@ package cz.jzitnik.game.entities.items.registry.blocks.blocks;
|
|||||||
|
|
||||||
import cz.jzitnik.game.SpriteLoader;
|
import cz.jzitnik.game.SpriteLoader;
|
||||||
import cz.jzitnik.game.annotations.BlockRegistry;
|
import cz.jzitnik.game.annotations.BlockRegistry;
|
||||||
|
import cz.jzitnik.game.annotations.Flamable;
|
||||||
import cz.jzitnik.game.entities.Block;
|
import cz.jzitnik.game.entities.Block;
|
||||||
import cz.jzitnik.game.entities.items.ItemType;
|
import cz.jzitnik.game.entities.items.ItemType;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@Flamable
|
||||||
@BlockRegistry("oak_planks")
|
@BlockRegistry("oak_planks")
|
||||||
public class OakPlanksBlock extends Block {
|
public class OakPlanksBlock extends Block {
|
||||||
public OakPlanksBlock() {
|
public OakPlanksBlock() {
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package cz.jzitnik.game.logic.services.farmable;
|
package cz.jzitnik.game.logic.services.farmable;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class FarmableData {
|
public class FarmableData implements Serializable {
|
||||||
private int age = 0;
|
private int age = 0;
|
||||||
private int state = 0;
|
private int state = 0;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
package cz.jzitnik.game.logic.services.firespreading;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import cz.jzitnik.game.Game;
|
||||||
|
import cz.jzitnik.game.annotations.CustomLogic;
|
||||||
|
import cz.jzitnik.game.annotations.Flamable;
|
||||||
|
import cz.jzitnik.game.entities.Block;
|
||||||
|
import cz.jzitnik.game.logic.CustomLogicInterface;
|
||||||
|
|
||||||
|
@CustomLogic
|
||||||
|
public class FireSpreadingLogic implements CustomLogicInterface {
|
||||||
|
private static final int RADIUS = 30;
|
||||||
|
private Random random = new Random();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void nextIteration(Game game) {
|
||||||
|
var world = game.getWorld();
|
||||||
|
int[] data = game.getPlayerCords();
|
||||||
|
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.isOnFire()) {
|
||||||
|
int maxTime = random.nextInt(30) + 15;
|
||||||
|
block.setBurningTime2(block.getBurningTime2() + 1);
|
||||||
|
if (block.getBurningTime2() >= maxTime) {
|
||||||
|
world[y][x].remove(block);
|
||||||
|
} else {
|
||||||
|
spreadFireToNeighbors(world, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void spreadFireToNeighbors(List<Block>[][] world, int x, int y) {
|
||||||
|
checkAndSpreadFire(world, x + 1, y);
|
||||||
|
checkAndSpreadFire(world, x - 1, y);
|
||||||
|
checkAndSpreadFire(world, x, y + 1);
|
||||||
|
checkAndSpreadFire(world, x, y - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAndSpreadFire(List<Block>[][] world, int x, int y) {
|
||||||
|
if (x < 0 || y < 0 || x >= world[0].length || y >= world.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var blocks = world[y][x];
|
||||||
|
|
||||||
|
for (Block block : blocks) {
|
||||||
|
if (block.getClass().isAnnotationPresent(Flamable.class) && !block.isOnFire()) {
|
||||||
|
int maxTime = random.nextInt(8) + 5;
|
||||||
|
block.setBurningTime(block.getBurningTime() + 1);
|
||||||
|
if (block.getBurningTime() >= maxTime) {
|
||||||
|
block.setOnFire(true);
|
||||||
|
block.setBurningTime(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -112,12 +112,20 @@ public class ScreenRenderer {
|
|||||||
sprites.add(stringBuilder.toString());
|
sprites.add(stringBuilder.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blocks.stream().anyMatch(block -> block.getBlockId().equals("steve") && block.getSpriteState().get() == Steve.SteveState.SECOND) && game.getPlayer().isBurningState()) {
|
if (blocks.stream()
|
||||||
|
.anyMatch(block -> block.getBlockId().equals("steve")
|
||||||
|
&& block.getSpriteState().get() == Steve.SteveState.SECOND)
|
||||||
|
&& game.getPlayer().isBurningState()) {
|
||||||
SimpleSprite fire = new SimpleSprite("fire.ans");
|
SimpleSprite fire = new SimpleSprite("fire.ans");
|
||||||
|
|
||||||
sprites.add(fire.getSprite());
|
sprites.add(fire.getSprite());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var burningBlocks = blocks.stream().filter(Block::isOnFire).toList();
|
||||||
|
if (!burningBlocks.isEmpty()) {
|
||||||
|
SimpleSprite fire = new SimpleSprite("fire.ans");
|
||||||
|
sprites.add(blocks.indexOf(burningBlocks.getLast()) + 1, fire.getSprite());
|
||||||
|
}
|
||||||
|
|
||||||
String sprite = SpriteCombiner.combineSprites(sprites.toArray(String[]::new));
|
String sprite = SpriteCombiner.combineSprites(sprites.toArray(String[]::new));
|
||||||
|
|
||||||
String[] spriteLines = sprite.split("\n");
|
String[] spriteLines = sprite.split("\n");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user