Skip to content

Commit f20a318

Browse files
committed
who sleep in bed overnight can heal properly now
1 parent 6afa943 commit f20a318

1 file changed

Lines changed: 90 additions & 19 deletions

File tree

src/main/java/huix/infinity/init/IFWEvents.java

Lines changed: 90 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
import huix.infinity.common.core.component.IFWDataComponents;
55
import huix.infinity.common.world.effect.UnClearEffect;
66
import huix.infinity.common.world.entity.player.LevelBonusStats;
7+
import huix.infinity.common.world.entity.player.NutritionalStatus;
78
import huix.infinity.common.world.food.IFWFoodProperties;
89
import huix.infinity.common.world.item.IFWItems;
10+
import huix.infinity.extension.func.FoodDataExtension;
911
import huix.infinity.init.event.IFWLoading;
1012
import huix.infinity.util.IFWEnchantmentHelper;
1113
import huix.infinity.util.WorldHelper;
@@ -19,6 +21,7 @@
1921
import net.minecraft.resources.ResourceKey;
2022
import net.minecraft.resources.ResourceLocation;
2123
import net.minecraft.server.level.ServerLevel;
24+
import net.minecraft.server.level.ServerPlayer;
2225
import net.minecraft.tags.ItemTags;
2326
import net.minecraft.world.effect.MobEffects;
2427
import net.minecraft.world.entity.EquipmentSlotGroup;
@@ -29,6 +32,7 @@
2932
import net.minecraft.world.item.ArmorItem;
3033
import net.minecraft.world.item.ItemStack;
3134
import net.minecraft.world.item.Items;
35+
import net.minecraft.world.level.GameRules;
3236
import net.minecraft.world.level.Level;
3337
import net.minecraft.world.level.LevelAccessor;
3438
import net.minecraft.world.level.block.Blocks;
@@ -45,18 +49,14 @@
4549
import net.neoforged.neoforge.event.LootTableLoadEvent;
4650
import net.neoforged.neoforge.event.entity.living.LivingDeathEvent;
4751
import net.neoforged.neoforge.event.entity.living.MobEffectEvent;
48-
import net.neoforged.neoforge.event.entity.player.CanContinueSleepingEvent;
49-
import net.neoforged.neoforge.event.entity.player.CriticalHitEvent;
50-
import net.neoforged.neoforge.event.entity.player.ItemTooltipEvent;
51-
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
52+
import net.neoforged.neoforge.event.entity.player.*;
5253
import net.neoforged.neoforge.event.furnace.FurnaceFuelBurnTimeEvent;
54+
import net.neoforged.neoforge.event.level.SleepFinishedTimeEvent;
5355
import net.neoforged.neoforge.event.level.block.CropGrowEvent;
5456
import net.neoforged.neoforge.event.tick.ServerTickEvent;
5557
import net.neoforged.neoforge.registries.datamaps.DataMapsUpdatedEvent;
5658

57-
import java.util.Iterator;
58-
import java.util.List;
59-
import java.util.Map;
59+
import java.util.*;
6060

6161
public class IFWEvents {
6262

@@ -172,7 +172,7 @@ private static void showFoodInfo(final FoodProperties food, final List<Component
172172
}
173173

174174
private static void showMoreFoodInfo(final IFWFoodProperties extraFood, final List<Component> list) {
175-
if (extraFood != null && Screen.hasAltDown()) {
175+
if (extraFood != null && Screen.hasAltDown()) {
176176
if (extraFood.protein() != 0)
177177
list.add(Component.translatable("foodtips.protein", extraFood.protein()).withStyle(ChatFormatting.YELLOW));
178178
if (extraFood.phytonutrients() != 0)
@@ -240,24 +240,95 @@ public static void onCropGrow(final CropGrowEvent.Pre event) {
240240

241241
@SubscribeEvent
242242
public static void onCalculatePlayerTurn(CalculatePlayerTurnEvent event) {
243-
// 获取玩家
243+
244244
LocalPlayer player = Minecraft.getInstance().player;
245245

246246
if (player != null && player.hasEffect(MobEffects.MOVEMENT_SLOWDOWN)) {
247-
// 获取缓慢效果等级
248-
int amplifier = player.getEffect(MobEffects.MOVEMENT_SLOWDOWN).getAmplifier();
249-
// 获取当前灵敏度
247+
248+
int amplifier = Objects.requireNonNull(player.getEffect(MobEffects.MOVEMENT_SLOWDOWN)).getAmplifier();
249+
250250
double sensitivity = event.getMouseSensitivity();
251-
// 根据缓慢等级降低灵敏度 (每级减少20%)
251+
252252
double reduction = 1.0 - ((amplifier + 1) * 0.2);
253-
// 设置新的灵敏度
253+
254254
event.setMouseSensitivity(sensitivity * reduction);
255255
}
256256
}
257257

258-
// @SubscribeEvent
259-
// public static void onSleepFinished(final SleepFinishedTimeEvent event) {
260-
//
261-
// }
258+
private static final Map<UUID, Long> playerSleepStartTime = new HashMap<>();
259+
260+
@SubscribeEvent
261+
public static void onCanPlayerSleep(final CanPlayerSleepEvent event) {
262+
ServerPlayer player = event.getEntity();
263+
264+
if (event.getProblem() == null) {
265+
long currentTime = player.level().getDayTime();
266+
playerSleepStartTime.put(player.getUUID(), currentTime);
267+
}
268+
}
269+
270+
@SubscribeEvent
271+
public static void onSleepFinished(final SleepFinishedTimeEvent event) {
272+
if (!(event.getLevel() instanceof ServerLevel serverLevel)) return;
273+
274+
long newTime = event.getNewTime();
275+
276+
// 为所有参与睡眠的玩家处理恢复
277+
for (ServerPlayer player : serverLevel.players()) {
278+
UUID playerUUID = player.getUUID();
279+
Long sleepStartTime = playerSleepStartTime.get(playerUUID);
262280

263-
}
281+
if (sleepStartTime != null) {
282+
// 计算实际跳过的游戏时间
283+
long actualSkippedTime = newTime - sleepStartTime;
284+
285+
// 确保跳过时间是合理的(至少1000 ticks)
286+
if (actualSkippedTime > 1000) {
287+
calculateSleepHealing(player, actualSkippedTime);
288+
}
289+
290+
playerSleepStartTime.remove(playerUUID);
291+
}
292+
}
293+
}
294+
295+
@SubscribeEvent
296+
public static void onPlayerWakeUp(final PlayerWakeUpEvent event) {
297+
Player player = event.getEntity();
298+
if (player.level().isClientSide()) return;
299+
300+
// 清理可能残留的睡眠记录(处理睡眠被打断等情况)
301+
playerSleepStartTime.remove(player.getUUID());
302+
}
303+
304+
private static void calculateSleepHealing(Player player, long skippedTime) {
305+
if (!player.level().getGameRules().getBoolean(GameRules.RULE_NATURAL_REGENERATION)) {
306+
return;
307+
}
308+
309+
if (player.getHealth() >= player.getMaxHealth()) {
310+
return;
311+
}
312+
313+
FoodDataExtension foodData = (FoodDataExtension) player.getFoodData();
314+
NutritionalStatus nutritionalStatus = foodData.ifw_nutritionalStatus();
315+
316+
int baseHealInterval = 1280;
317+
int adjustedInterval = baseHealInterval * nutritionalStatus.naturalHealSpeedTimes();
318+
int sleepHealInterval = adjustedInterval / 8;
319+
int healCount = (int) (skippedTime / sleepHealInterval);
320+
321+
if (healCount > 0) {
322+
float maxHealth = player.getMaxHealth();
323+
float currentHealth = player.getHealth();
324+
float maxPossibleHeal = maxHealth - currentHealth;
325+
float actualHeal = Math.min(healCount, maxPossibleHeal);
326+
327+
if (actualHeal > 0) {
328+
player.heal(actualHeal);
329+
float exhaustionCost = actualHeal * 6.0F;
330+
player.getFoodData().addExhaustion(exhaustionCost);
331+
}
332+
}
333+
}
334+
}

0 commit comments

Comments
 (0)