diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index fa43cdc50a9..e3319c480d5 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -1456,7 +1456,7 @@ protected void processMovement(int tickDiff) { } } - Location from = new Location( + Location from = new Location( this.lastX, this.lastY, this.lastZ, @@ -1511,25 +1511,23 @@ protected void processMovement(int tickDiff) { else this.speed.setComponents(0, 0, 0); } - if (!revert && (this.isFoodEnabled() || this.getServer().getDifficulty() == 0)) { + if (!revert) { if ((this.isSurvival() || this.isAdventure())/* && !this.getRiddingOn() instanceof Entity*/) { //UpdateFoodExpLevel - if (distance >= 0.05) { - double jump = 0; - double swimming = this.isInsideOfWater() ? 0.015 * distance : 0; - if (swimming != 0) distance = 0; - if (this.isSprinting()) { //Running - if (this.inAirTicks == 3 && swimming == 0) { - jump = 0.7; - } - this.getFoodData().updateFoodExpLevel(0.06 * distance + jump + swimming); - } else { - if (this.inAirTicks == 3 && swimming == 0) { - jump = 0.2; - } - this.getFoodData().updateFoodExpLevel(0.01 * distance + jump + swimming); + double jump = 0; + double swimming = this.isInsideOfWater() ? 0.01 * distance : 0; + if (swimming != 0) distance = 0; + if (this.isSprinting()) { //Running + if (this.inAirTicks == 3 && swimming == 0) { + jump = 0.2; } + this.getFoodData().updateFoodExpLevel(0.1 * distance + jump + swimming); + } else { + if (this.inAirTicks == 3 && swimming == 0) { + jump = 0.05; + } + this.getFoodData().updateFoodExpLevel(jump + swimming); } } } @@ -1638,15 +1636,23 @@ public boolean onUpdate(int currentTick) { this.entityBaseTick(tickDiff); - if (this.getServer().getDifficulty() == 0 && this.level.getGameRules().getBoolean(GameRule.NATURAL_REGENERATION)) { - if (this.getHealth() < this.getMaxHealth() && this.ticksLived % 20 == 0) { - this.heal(1); - } + if (this.getHealth() < this.getMaxHealth() && !this.server.isHardcore() && this.level.getGameRules().getBoolean(GameRule.NATURAL_REGENERATION)) { + if (this.getServer().getDifficulty() == 0) { + if (this.ticksLived % 20 == 0) { + this.heal(1); + } - PlayerFood foodData = this.getFoodData(); + PlayerFood foodData = this.getFoodData(); + if (foodData.getLevel() < 20 && this.ticksLived % 10 == 0) { + foodData.addFoodLevel(1, 0); + } + } - if (foodData.getLevel() < 20 && this.ticksLived % 10 == 0) { - foodData.addFoodLevel(1, 0); + if (this.ticksLived % 80 == 0 && this.getFoodData().getLevel() >= 18) { + this.heal(1); + if (this.getServer().getDifficulty() > 0) { + this.getFoodData().updateFoodExpLevel(0.6); + } } } @@ -3102,7 +3108,7 @@ public void onCompletion(Server server) { if (this.canInteract(blockVector.add(0.5, 0.5, 0.5), this.isCreative() ? 13 : 7) && (i = this.level.useBreakOn(blockVector.asVector3(), face, i, this, true)) != null) { if (this.isSurvival()) { - this.getFoodData().updateFoodExpLevel(0.025); + this.getFoodData().updateFoodExpLevel(0.005); if (!i.equals(oldItem) || i.getCount() != oldItem.getCount()) { inventory.setItemInHand(i); inventory.sendHeldItem(this.getViewers().values()); @@ -4168,7 +4174,7 @@ public boolean attack(EntityDamageEvent source) { if (source instanceof EntityDamageByEntityEvent) { Entity damager = ((EntityDamageByEntityEvent) source).getDamager(); if (damager instanceof Player) { - ((Player) damager).getFoodData().updateFoodExpLevel(0.3); + ((Player) damager).getFoodData().updateFoodExpLevel(0.1); } } EntityEventPacket pk = new EntityEventPacket(); @@ -4176,6 +4182,7 @@ public boolean attack(EntityDamageEvent source) { pk.event = EntityEventPacket.HURT_ANIMATION; this.dataPacket(pk); } + this.getFoodData().updateFoodExpLevel(0.1); return true; } else { return false; diff --git a/src/main/java/cn/nukkit/PlayerFood.java b/src/main/java/cn/nukkit/PlayerFood.java index 40ceb867c9b..a895cee7e47 100644 --- a/src/main/java/cn/nukkit/PlayerFood.java +++ b/src/main/java/cn/nukkit/PlayerFood.java @@ -103,6 +103,7 @@ public void useHunger(int amount) { float newSfl = sfl - amount; if (newSfl < 0) newSfl = 0; this.setFoodSaturationLevel(newSfl); + this.sendFoodLevel(); } else { this.setLevel(foodLevel - amount); } @@ -171,12 +172,16 @@ public void update(int tickDiff) { } public void updateFoodExpLevel(double use) { - if (!this.getPlayer().isFoodEnabled()) return; if (Server.getInstance().getDifficulty() == 0) return; if (this.getPlayer().hasEffect(Effect.SATURATION)) return; this.foodExpLevel += use; if (this.foodExpLevel > 4) { - this.useHunger(1); + if (!this.getPlayer().isFoodEnabled()) { + // Hack to get around the client reducing food despite us not sending the attribute + this.sendFoodLevel(); + } else { + this.useHunger(1); + } this.foodExpLevel = 0; } }