feat: Added cow
This commit is contained in:
@ -41,6 +41,7 @@ public class SpriteLoader {
|
||||
STEVE,
|
||||
PIG,
|
||||
SHEEP,
|
||||
COW,
|
||||
|
||||
// UI
|
||||
BREAKING,
|
||||
@ -147,6 +148,7 @@ public class SpriteLoader {
|
||||
SPRITES_MAP.put(SPRITES.STEVE, new Steve());
|
||||
SPRITES_MAP.put(SPRITES.PIG, new Pig());
|
||||
SPRITES_MAP.put(SPRITES.SHEEP, new Sheep());
|
||||
SPRITES_MAP.put(SPRITES.COW, new Cow());
|
||||
|
||||
// UI
|
||||
SPRITES_MAP.put(SPRITES.BREAKING, new Breaking());
|
||||
@ -215,13 +217,6 @@ public class SpriteLoader {
|
||||
SPRITES_MAP.put(SPRITES.ITEM_COOKED_PORKCHOP, new SimpleSprite("items/cooked_porkchop.ans"));
|
||||
SPRITES_MAP.put(SPRITES.ITEM_MUTTON, new SimpleSprite("items/mutton.ans"));
|
||||
SPRITES_MAP.put(SPRITES.ITEM_COOKED_MUTTON, new SimpleSprite("items/cooked_mutton.ans"));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static SpriteList<SPRITES> load() {
|
||||
|
@ -0,0 +1,16 @@
|
||||
package cz.jzitnik.game.entities.items.registry.blocks;
|
||||
|
||||
import cz.jzitnik.game.SpriteLoader;
|
||||
import cz.jzitnik.game.annotations.BlockRegistry;
|
||||
import cz.jzitnik.game.entities.Block;
|
||||
import cz.jzitnik.game.entities.items.ItemType;
|
||||
import cz.jzitnik.game.entities.items.ToolVariant;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@BlockRegistry("iron_ore")
|
||||
public class IronOreBlock extends Block {
|
||||
public IronOreBlock() {
|
||||
super("iron_ore", SpriteLoader.SPRITES.IRON_ORE, 15, ItemType.PICKAXE, Arrays.stream(ToolVariant.values()).toList());
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package cz.jzitnik.game.entities.items.registry.items;
|
||||
|
||||
import cz.jzitnik.game.SpriteLoader;
|
||||
import cz.jzitnik.game.annotations.ItemRegistry;
|
||||
import cz.jzitnik.game.entities.items.Item;
|
||||
import cz.jzitnik.game.entities.items.ItemType;
|
||||
|
||||
@ItemRegistry("coal")
|
||||
public class CoalItem extends Item {
|
||||
public CoalItem() {
|
||||
super("coal", "Coal", ItemType.USELESS_ITEM, SpriteLoader.SPRITES.ITEM_COAL_ORE);
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package cz.jzitnik.game.entities.items.registry.items;
|
||||
|
||||
import cz.jzitnik.game.SpriteLoader;
|
||||
import cz.jzitnik.game.annotations.ItemRegistry;
|
||||
import cz.jzitnik.game.entities.items.Item;
|
||||
import cz.jzitnik.game.entities.items.ItemType;
|
||||
|
||||
@ItemRegistry("iron_ore")
|
||||
public class IronOreItem extends Item {
|
||||
public IronOreItem() {
|
||||
super("iron_ore", "Iron ore", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_IRON_ORE);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package cz.jzitnik.game.entities.items.registry.mobs;
|
||||
|
||||
import cz.jzitnik.game.SpriteLoader;
|
||||
import cz.jzitnik.game.annotations.EntityRegistry;
|
||||
import cz.jzitnik.game.entities.Block;
|
||||
import cz.jzitnik.game.mobs.services.cow.CowData;
|
||||
|
||||
@EntityRegistry("cow")
|
||||
public class Cow extends Block {
|
||||
public Cow() {
|
||||
super("cow", SpriteLoader.SPRITES.COW);
|
||||
setMob(true);
|
||||
setGhost(true);
|
||||
setSpriteState(cz.jzitnik.game.sprites.Cow.CowState.RIGHT);
|
||||
setMineable(false);
|
||||
setData(new CowData());
|
||||
setHp(10);
|
||||
}
|
||||
}
|
12
src/main/java/cz/jzitnik/game/mobs/services/cow/CowData.java
Normal file
12
src/main/java/cz/jzitnik/game/mobs/services/cow/CowData.java
Normal file
@ -0,0 +1,12 @@
|
||||
package cz.jzitnik.game.mobs.services.cow;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class CowData {
|
||||
private int lastDirection = 1; // 1 = right, -1 = left
|
||||
private int movementCooldown = 0;
|
||||
private int jumpAttempts = 0;
|
||||
}
|
205
src/main/java/cz/jzitnik/game/mobs/services/cow/CowLogic.java
Normal file
205
src/main/java/cz/jzitnik/game/mobs/services/cow/CowLogic.java
Normal file
@ -0,0 +1,205 @@
|
||||
package cz.jzitnik.game.mobs.services.cow;
|
||||
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.annotations.EntityHurtAnimationHandler;
|
||||
import cz.jzitnik.game.annotations.EntityKillHandler;
|
||||
import cz.jzitnik.game.annotations.EntityLogic;
|
||||
import cz.jzitnik.game.annotations.EntitySpawn;
|
||||
import cz.jzitnik.game.entities.Block;
|
||||
import cz.jzitnik.game.entities.items.InventoryItem;
|
||||
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
|
||||
import cz.jzitnik.game.mobs.*;
|
||||
import cz.jzitnik.game.sprites.Cow;
|
||||
import cz.jzitnik.tui.ScreenMovingCalculationProvider;
|
||||
import org.jline.terminal.Terminal;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static cz.jzitnik.game.sprites.Cow.CowState.*;
|
||||
|
||||
@EntitySpawn
|
||||
@EntityLogic("cow")
|
||||
@EntityHurtAnimationHandler("cow")
|
||||
@EntityKillHandler("cow")
|
||||
public class CowLogic implements EntityLogicInterface, EntitySpawnInterface, EntityHurtAnimationChanger, EntityKillInterface {
|
||||
private final Random random = new Random();
|
||||
|
||||
@Override
|
||||
public void nextIteration(EntityLogicProvider.EntityLogicMobDTO entityLogicMobDTO) {
|
||||
int cowX = entityLogicMobDTO.getX();
|
||||
int cowY = entityLogicMobDTO.getY();
|
||||
var game = entityLogicMobDTO.getGame();
|
||||
var cow = entityLogicMobDTO.getMob();
|
||||
var world = game.getWorld();
|
||||
var cowData = (CowData) cow.getData();
|
||||
|
||||
boolean updated = false;
|
||||
int newCowX = cowX;
|
||||
int newCowY = cowY;
|
||||
|
||||
if (cowData.getMovementCooldown() > 0) {
|
||||
cowData.setMovementCooldown(cowData.getMovementCooldown() - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
int direction = cowData.getLastDirection();
|
||||
if (random.nextInt(10) < 1) { // 10% chance to change direction
|
||||
direction = -direction;
|
||||
}
|
||||
cowData.setLastDirection(direction);
|
||||
|
||||
if (direction == 1) {
|
||||
if (cow.getSpriteState().get() == RIGHT_HURT || cow.getSpriteState().get() == LEFT_HURT) {
|
||||
cow.setSpriteState(RIGHT_HURT);
|
||||
} else {
|
||||
cow.setSpriteState(RIGHT);
|
||||
}
|
||||
} else {
|
||||
if (cow.getSpriteState().get() == RIGHT_HURT || cow.getSpriteState().get() == LEFT_HURT) {
|
||||
cow.setSpriteState(LEFT_HURT);
|
||||
} else {
|
||||
cow.setSpriteState(LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
List<Block> blocksAhead = world[cowY][cowX + direction];
|
||||
if (!game.isSolid(blocksAhead)) {
|
||||
world[cowY][cowX].remove(cow);
|
||||
world[cowY][cowX + direction].add(cow);
|
||||
newCowX = cowX + direction;
|
||||
updated = true;
|
||||
cowData.setJumpAttempts(0);
|
||||
} else {
|
||||
List<Block> blocksAboveAhead = world[cowY - 1][cowX + direction];
|
||||
List<Block> blocksTwoAboveAhead = world[cowY - 2][cowX + direction];
|
||||
|
||||
if (!game.isSolid(blocksAboveAhead) && game.isSolid(blocksAhead) && !game.isSolid(blocksTwoAboveAhead)) {
|
||||
if (cowData.getJumpAttempts() < 2) {
|
||||
world[cowY][cowX].remove(cow);
|
||||
world[cowY - 1][cowX + direction].add(cow);
|
||||
newCowX = cowX + direction;
|
||||
newCowY = cowY - 1;
|
||||
updated = true;
|
||||
cowData.setJumpAttempts(cowData.getJumpAttempts() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (updated) {
|
||||
if (!game.isSolid(world[newCowY + 1][newCowX])) {
|
||||
if (newCowY - cowY < 3) {
|
||||
world[newCowY][newCowX].remove(cow);
|
||||
world[newCowY + 1][newCowX].add(cow);
|
||||
newCowY++;
|
||||
} else {
|
||||
updated = false;
|
||||
}
|
||||
} else {
|
||||
updated = false;
|
||||
}
|
||||
}
|
||||
|
||||
cowData.setMovementCooldown(random.nextInt(3) + 1); // 1-3 iterations cooldown
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawn(int playerX, int playerY, Game game, Terminal terminal) {
|
||||
// Cordinates where player can see
|
||||
int[] data = ScreenMovingCalculationProvider.calculate(playerX, playerY, terminal.getHeight(), terminal.getWidth(), game.getWorld()[0].length, game.getWorld().length);
|
||||
var world = game.getWorld();
|
||||
int startX = data[0];
|
||||
int endX = data[1];
|
||||
|
||||
// Left side
|
||||
int lstartX = startX - 20;
|
||||
int lendX = startX - 5;
|
||||
int lstartY = playerY - 15;
|
||||
int lendY = playerY + 15;
|
||||
|
||||
if (countCows(lstartX, lendX, lstartY, lendY, game) < 3 && random.nextInt(100) < 100) {
|
||||
var spawnLocations = cowCanSpawn(lstartX, lendX, playerY, game);
|
||||
if (!spawnLocations.isEmpty()) {
|
||||
for (int i = 0; i < Math.min(4, spawnLocations.size()); i++) {
|
||||
var randomLocation = getRandomEntry(spawnLocations);
|
||||
int x = randomLocation.getKey();
|
||||
int y = randomLocation.getValue();
|
||||
|
||||
world[y][x].add(ItemBlockSupplier.getEntity("cow"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Right side
|
||||
int rstartX = endX + 5;
|
||||
int rendX = endX + 20;
|
||||
int rstartY = playerY - 15;
|
||||
int rendY = playerY + 15;
|
||||
|
||||
if (countCows(rstartX, rendX, rstartY, rendY, game) < 3 && random.nextInt(100) < 2) {
|
||||
var spawnLocations = cowCanSpawn(rstartX, rendX, playerY, game);
|
||||
if (!spawnLocations.isEmpty()) {
|
||||
for (int i = 0; i < Math.min(random.nextInt(3) + 2, spawnLocations.size()); i++) {
|
||||
var randomLocation = getRandomEntry(spawnLocations);
|
||||
int x = randomLocation.getKey();
|
||||
int y = randomLocation.getValue();
|
||||
|
||||
world[y][x].add(ItemBlockSupplier.getEntity("cow"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static <K, V> Map.Entry<K, V> getRandomEntry(HashMap<K, V> map) {
|
||||
List<Map.Entry<K, V>> entryList = new ArrayList<>(map.entrySet());
|
||||
Random random = new Random();
|
||||
return entryList.get(random.nextInt(entryList.size()));
|
||||
}
|
||||
|
||||
private HashMap<Integer, Integer> cowCanSpawn(int startX, int endX, int playerY, Game game) {
|
||||
var map = new HashMap<Integer, Integer>();
|
||||
var world = game.getWorld();
|
||||
for (int x = startX; x <= endX; x++) {
|
||||
for (int y = Math.max(0, playerY - 30); y < Math.min(world.length, playerY + 30); y++) {
|
||||
if (world[y][x].stream().anyMatch(i -> i.getBlockId().equals("grass"))) {
|
||||
map.put(x, y - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private long countCows(int startX, int endX, int startY, int endY, Game game) {
|
||||
long cowAmount = 0;
|
||||
for (int y = startY; y <= endY; y++) {
|
||||
for (int x = startX; x <= endX; x++) {
|
||||
cowAmount += game.getWorld()[y][x].stream().filter(i -> i.getBlockId().equals("cow")).count();
|
||||
}
|
||||
}
|
||||
|
||||
return cowAmount;
|
||||
}
|
||||
|
||||
public Cow.CowState setHurtAnimation(boolean hurt, Enum current) {
|
||||
if (hurt) {
|
||||
return switch (current) {
|
||||
case LEFT_HURT,LEFT -> LEFT_HURT;
|
||||
case RIGHT_HURT,RIGHT -> RIGHT_HURT;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + current);
|
||||
};
|
||||
}
|
||||
|
||||
return switch (current) {
|
||||
case LEFT_HURT,LEFT -> LEFT;
|
||||
case RIGHT_HURT,RIGHT -> RIGHT;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + current);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void killed(Game game, Block mob) {
|
||||
/*int amount = random.nextInt(2) + 1;
|
||||
InventoryItem inventoryItem = new InventoryItem(amount, ItemBlockSupplier.getItem("mutton"));
|
||||
game.getInventory().addItem(inventoryItem);*/
|
||||
}
|
||||
}
|
29
src/main/java/cz/jzitnik/game/sprites/Cow.java
Normal file
29
src/main/java/cz/jzitnik/game/sprites/Cow.java
Normal file
@ -0,0 +1,29 @@
|
||||
package cz.jzitnik.game.sprites;
|
||||
|
||||
import cz.jzitnik.tui.ResourceLoader;
|
||||
import cz.jzitnik.tui.Sprite;
|
||||
|
||||
public class Cow extends Sprite {
|
||||
public enum CowState{
|
||||
LEFT,
|
||||
RIGHT,
|
||||
LEFT_HURT,
|
||||
RIGHT_HURT
|
||||
}
|
||||
|
||||
public String getSprite() {
|
||||
return getSprite(CowState.RIGHT);
|
||||
}
|
||||
|
||||
public String getSprite(Enum e) {
|
||||
return ResourceLoader.loadResource(
|
||||
switch (e) {
|
||||
case CowState.LEFT -> "mobs/cow/left.ans";
|
||||
case CowState.RIGHT -> "mobs/cow/right.ans";
|
||||
case CowState.LEFT_HURT -> "mobs/cow/lefthurt.ans";
|
||||
case CowState.RIGHT_HURT -> "mobs/cow/righthurt.ans";
|
||||
default -> throw new IllegalStateException("Unexpected value: " + e);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user