Skip to content

Commit

Permalink
refactor: better hunger & save hunger
Browse files Browse the repository at this point in the history
* feat: difficulty command
  • Loading branch information
IWareQ committed Jul 13, 2024
1 parent 6a1cf92 commit 51c8b81
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.allaymc.api.entity.interfaces.EntityPlayer;
import org.allaymc.api.item.enchantment.EnchantmentType;
import org.allaymc.api.item.type.ItemType;
import org.allaymc.api.world.Difficulty;
import org.cloudburstmc.protocol.bedrock.data.GameType;
import org.cloudburstmc.protocol.bedrock.data.command.CommandParamData;
import org.cloudburstmc.protocol.bedrock.data.command.CommandParamOption;
Expand Down Expand Up @@ -295,4 +296,12 @@ default CommandNode itemTypeNode(String name) {
default CommandNode itemTypeNode(String name, ItemType<?> defaultValue) {
return addLeaf(getFactory().itemTypeNode(name, this, defaultValue));
}

default CommandNode difficultyNode(String name) {
return difficultyNode(name, null);
}

default CommandNode difficultyNode(String name, Difficulty defaultValue) {
return addLeaf(getFactory().difficultyNode(name, this, defaultValue));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.allaymc.api.entity.interfaces.EntityPlayer;
import org.allaymc.api.item.enchantment.EnchantmentType;
import org.allaymc.api.item.type.ItemType;
import org.allaymc.api.world.Difficulty;
import org.cloudburstmc.protocol.bedrock.data.GameType;
import org.joml.Vector3fc;

Expand Down Expand Up @@ -67,4 +68,6 @@ static CommandNodeFactory getFactory() {
CommandNode effectNode(String name, CommandNode parent, EffectType defaultValue);

CommandNode itemTypeNode(String name, CommandNode parent, ItemType<?> defaultValue);

CommandNode difficultyNode(String name, CommandNode parent, Difficulty defaultValue);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public interface EntityPlayerHungerComponent extends EntityComponent {

void saturate(int food, float saturation);

boolean canEat();

int getFoodLevel();

void setFoodLevel(int foodLevel);
Expand All @@ -22,13 +24,11 @@ public interface EntityPlayerHungerComponent extends EntityComponent {

void setFoodSaturationLevel(float saturationLevel);

float getFoodTickTimer();

void setFoodTickTimer(float foodTickTimer);

float getFoodExhaustionLevel();

void setFoodExhaustionLevel(float foodExhaustionLevel);

boolean canEat();
int getFoodTickTimer();

void setFoodTickTimer(int foodTickTimer);
}
13 changes: 12 additions & 1 deletion Allay-API/src/main/java/org/allaymc/api/world/Difficulty.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,18 @@ public static Difficulty from(int value) {
case 0 -> Difficulty.PEACEFUL;
case 1 -> Difficulty.EASY;
case 2 -> Difficulty.NORMAL;
default -> Difficulty.HARD;
case 3 -> Difficulty.HARD;
default -> null;
};
}

public static Difficulty from(String value) {
return switch (value) {
case "peaceful", "p" -> Difficulty.PEACEFUL;
case "easy", "e" -> Difficulty.EASY;
case "normal", "n" -> Difficulty.NORMAL;
case "hard", "h" -> Difficulty.HARD;
default -> null;
};
}
}
8 changes: 8 additions & 0 deletions Allay-API/src/main/java/org/allaymc/api/world/World.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,12 @@ default void broadcastPacket(BedrockPacket packet) {
}

EventBus getEventBus();

default Difficulty getDifficulty() {
return getWorldData().getDifficulty();
}

default void setDifficulty(Difficulty difficulty) {
getWorldData().setDifficulty(difficulty);
}
}
4 changes: 2 additions & 2 deletions Allay-API/src/main/java/org/allaymc/api/world/WorldData.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ public class WorldData {

// NOTICE: The following values are used
@Builder.Default
Difficulty difficulty = Difficulty.from(1);
Difficulty difficulty = Difficulty.EASY;
@Builder.Default
boolean forceGameType = false;
@Builder.Default
org.cloudburstmc.protocol.bedrock.data.GameType gameType = GameType.from(1);
org.cloudburstmc.protocol.bedrock.data.GameType gameType = GameType.CREATIVE;
@Builder.Default
String name = "Bedrock level";
@Builder.Default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
public class AllayCommandRegistry extends SimpleMappedRegistry<String, Command, Map<String, Command>> implements CommandRegistry {

public AllayCommandRegistry() {
super(null, i -> new ConcurrentHashMap<>());
super(null, $ -> new ConcurrentHashMap<>());
}

@Override
Expand Down Expand Up @@ -60,6 +60,7 @@ public void registerDefaultCommands() {
register(new EnchantCommand());
register(new EffectCommand());
register(new GiveCommand());
register(new DifficultyCommand());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.allaymc.server.command.defaults;

import org.allaymc.api.command.SenderType;
import org.allaymc.api.command.SimpleCommand;
import org.allaymc.api.command.tree.CommandTree;
import org.allaymc.api.i18n.TrKeys;
import org.allaymc.api.world.Difficulty;

/**
* Allay Project 13/07/2024
*
* @author IWareQ
*/
public class DifficultyCommand extends SimpleCommand {
public DifficultyCommand() {
super("difficulty", TrKeys.M_COMMANDS_DIFFICULTY_DESCRIPTION);
}

@Override
public void prepareCommandTree(CommandTree tree) {
tree.getRoot().difficultyNode("difficulty").exec((context, player) -> {
Difficulty difficulty = context.getResult(0);
player.getWorld().setDifficulty(difficulty);
context.addOutput(TrKeys.M_COMMANDS_DIFFICULTY_SUCCESS, difficulty);
return context.success();
}, SenderType.PLAYER);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.allaymc.api.entity.interfaces.EntityPlayer;
import org.allaymc.api.item.enchantment.EnchantmentType;
import org.allaymc.api.item.type.ItemType;
import org.allaymc.api.world.Difficulty;
import org.allaymc.server.command.tree.node.*;
import org.cloudburstmc.protocol.bedrock.data.GameType;
import org.joml.Vector3fc;
Expand Down Expand Up @@ -128,4 +129,9 @@ public CommandNode effectNode(String name, CommandNode parent, EffectType defaul
public CommandNode itemTypeNode(String name, CommandNode parent, ItemType<?> defaultValue) {
return new ItemTypeNode(name, parent, defaultValue);
}

@Override
public CommandNode difficultyNode(String name, CommandNode parent, Difficulty defaultValue) {
return new DifficultyNode(name, parent, defaultValue);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.allaymc.server.command.tree.node;

import org.allaymc.api.command.tree.CommandNode;
import org.allaymc.api.world.Difficulty;

/**
* Allay Project 13/07/2024
*
* @author IWareQ
*/
public class DifficultyNode extends EnumNode {
private static final String[] VALUES = new String[]{
"peaceful", "p", "0",
"easy", "e", "1",
"normal", "n", "2",
"hard", "h", "3"
};

public DifficultyNode(String name, CommandNode parent, Difficulty defaultValue) {
super(name, parent, defaultValue, VALUES);
}

@Override
protected Difficulty argToResult(String arg) {
try {
return Difficulty.from(Integer.parseInt(arg));
} catch (NumberFormatException ignored) {
return Difficulty.from(arg);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,10 @@ public NbtMap saveNBT() {
"Armor",
NbtType.COMPOUND,
containerHolderComponent.getContainer(FullContainerType.ARMOR).saveNBT())
.putFloat("foodExhaustionLevel", hungerComponent.getFoodExhaustionLevel())
.putInt("foodLevel", hungerComponent.getFoodLevel())
.putFloat("foodSaturationLevel", hungerComponent.getFoodSaturationLevel())
.putInt("foodTickTimer", hungerComponent.getFoodTickTimer())
.build();
}

Expand All @@ -448,6 +452,10 @@ public void loadNBT(NbtMap nbt) {
nbt.listenForList("Armor", NbtType.COMPOUND, armorNbt ->
containerHolderComponent.getContainer(FullContainerType.ARMOR).loadNBT(armorNbt)
);
nbt.listenForFloat("foodExhaustionLevel", hungerComponent::setFoodExhaustionLevel);
nbt.listenForInt("foodLevel", hungerComponent::setFoodLevel);
nbt.listenForFloat("foodSaturationLevel", hungerComponent::setFoodSaturationLevel);
nbt.listenForInt("foodTickTimer", hungerComponent::setFoodTickTimer);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@
public class EntityPlayerHungerComponentImpl implements EntityPlayerHungerComponent {
@ComponentIdentifier
public static final Identifier IDENTIFIER = new Identifier("minecraft:player_hunger_component");

private static final int MAX_FOOD_LEVEL = 20;

@ComponentedObject
protected EntityPlayer player;

private int foodLevel = MAX_FOOD_LEVEL;
private float foodSaturationLevel = 5f;

private float foodTickTimer;
private float foodExhaustionLevel;

private int foodTickTimer;

@Override
public void tickHunger() {
if (
Expand All @@ -44,15 +45,24 @@ public void tickHunger() {

foodTickTimer++;
if (foodTickTimer >= 80) foodTickTimer = 0;
if (foodTickTimer % 10 == 0) {
if (player.getWorld().getWorldData().getDifficulty() == Difficulty.PEACEFUL) setFoodLevel(foodLevel + 1);
if (foodLevel == MAX_FOOD_LEVEL && foodSaturationLevel > 0 && foodTickTimer % 20 == 0) regenerate(false);

var difficulty = player.getWorld().getWorldData().getDifficulty();
if (difficulty == Difficulty.PEACEFUL && foodTickTimer % 10 == 0) {
setFoodLevel(foodLevel + 1);

if (foodTickTimer % 20 == 0) regenerate(false);
}

if (foodTickTimer == 0) {
if (foodTickTimer == 0 && difficulty != Difficulty.PEACEFUL) {
if (foodLevel >= 18) regenerate(true);
else if (foodLevel == 0) {
if (player.getHealth() > 2) player.attack(DamageContainer.starve(1));
if (
(difficulty == Difficulty.EASY && player.getHealth() > 10) ||
(difficulty == Difficulty.NORMAL && player.getHealth() > 1) ||
difficulty == Difficulty.HARD
) {
player.attack(DamageContainer.starve(1));
}
}
}

Expand Down Expand Up @@ -114,24 +124,26 @@ public void saturate(int food, float saturation) {
private void regenerate(boolean exhaust) {
if (player.getHealth() == player.getMaxHealth()) return;

// TODO: normal heal method
// TODO: normal heal method with event
player.setHealth(player.getHealth() + 1);
if (exhaust) player.exhaust(6);
}

@Override
public boolean canEat() {
return getFoodLevel() < MAX_FOOD_LEVEL ||
player.getGameType() == GameType.CREATIVE ||
player.getWorld().getWorldData().getDifficulty() == Difficulty.PEACEFUL;
}

@Override
public void setFoodLevel(int foodLevel) {
// TODO: event
this.foodLevel = Math.max(Math.min(foodLevel, MAX_FOOD_LEVEL), 0);
}

@Override
public void setFoodTickTimer(float foodTickTimer) {
public void setFoodTickTimer(int foodTickTimer) {
this.foodTickTimer = Math.max(foodTickTimer, 0);
}

@Override
public boolean canEat() {
return getFoodLevel() < MAX_FOOD_LEVEL || player.getGameType() == GameType.CREATIVE || player.getWorld().getWorldData().getDifficulty() == Difficulty.PEACEFUL;
}
}

0 comments on commit 51c8b81

Please sign in to comment.