refactor sanity calculation logic; add new sources of sanity gain/loss and improve event handling
This commit is contained in:
@@ -2,7 +2,10 @@ package net.fretux.mindmotion.event;
|
|||||||
|
|
||||||
import net.fretux.mindmotion.player.PlayerCapabilityProvider;
|
import net.fretux.mindmotion.player.PlayerCapabilityProvider;
|
||||||
import net.fretux.mindmotion.player.SanityCapability;
|
import net.fretux.mindmotion.player.SanityCapability;
|
||||||
|
import net.minecraft.world.entity.monster.Monster;
|
||||||
|
import net.minecraft.world.entity.npc.Villager;
|
||||||
import net.minecraftforge.event.entity.living.LivingHurtEvent;
|
import net.minecraftforge.event.entity.living.LivingHurtEvent;
|
||||||
|
import net.minecraftforge.event.entity.living.LivingDeathEvent;
|
||||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
|
||||||
@@ -13,7 +16,22 @@ public class CommonEvents {
|
|||||||
if (!(event.getEntity() instanceof net.minecraft.world.entity.player.Player player)) return;
|
if (!(event.getEntity() instanceof net.minecraft.world.entity.player.Player player)) return;
|
||||||
if (player.level().isClientSide) return;
|
if (player.level().isClientSide) return;
|
||||||
|
|
||||||
player.getCapability(PlayerCapabilityProvider.SANITY).ifPresent(sanity -> sanity.reduceSanity(1));
|
float loss = Math.min(5f, 0.5f + event.getAmount() * 0.25f);
|
||||||
|
player.getCapability(PlayerCapabilityProvider.SANITY).ifPresent(sanity -> sanity.reduceSanity(loss));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void onLivingDeath(LivingDeathEvent event) {
|
||||||
|
if (!(event.getSource().getEntity() instanceof net.minecraft.world.entity.player.Player player)) return;
|
||||||
|
if (player.level().isClientSide) return;
|
||||||
|
|
||||||
|
player.getCapability(PlayerCapabilityProvider.SANITY).ifPresent(sanity -> {
|
||||||
|
if (event.getEntity() instanceof Monster) {
|
||||||
|
sanity.addSanity(0.75f);
|
||||||
|
} else if (event.getEntity() instanceof Villager) {
|
||||||
|
sanity.reduceSanity(4f);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import net.fretux.mindmotion.ConfigMM;
|
|||||||
import net.fretux.mindmotion.network.ModMessages;
|
import net.fretux.mindmotion.network.ModMessages;
|
||||||
import net.fretux.mindmotion.network.SyncStatsS2CPacket;
|
import net.fretux.mindmotion.network.SyncStatsS2CPacket;
|
||||||
import net.fretux.mindmotion.player.PlayerCapabilityProvider;
|
import net.fretux.mindmotion.player.PlayerCapabilityProvider;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.tags.BlockTags;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.tags.BiomeTags;
|
import net.minecraft.tags.BiomeTags;
|
||||||
import net.minecraft.world.effect.MobEffectInstance;
|
import net.minecraft.world.effect.MobEffectInstance;
|
||||||
@@ -89,13 +91,14 @@ public class PlayerTickHandler {
|
|||||||
boolean sleeping = player.isSleeping();
|
boolean sleeping = player.isSleeping();
|
||||||
boolean inLight = player.level().getMaxLocalRawBrightness(player.blockPosition()) > 12;
|
boolean inLight = player.level().getMaxLocalRawBrightness(player.blockPosition()) > 12;
|
||||||
boolean nearTorch = player.level().getBlockState(player.blockPosition().above()).is(Blocks.TORCH);
|
boolean nearTorch = player.level().getBlockState(player.blockPosition().above()).is(Blocks.TORCH);
|
||||||
|
int light = player.level().getMaxLocalRawBrightness(player.blockPosition());
|
||||||
|
|
||||||
if (inDark) delta -= ConfigMM.COMMON.BASE_SANITY_DECAY_DARK.get().floatValue();
|
if (inDark) delta -= ConfigMM.COMMON.BASE_SANITY_DECAY_DARK.get().floatValue();
|
||||||
if (inRain) delta -= 0.04f;
|
if (inRain) delta -= 0.04f;
|
||||||
if (isHungry) delta -= 0.06f;
|
if (isHungry) delta -= 0.06f;
|
||||||
if (nearLava) delta -= 0.05f;
|
if (nearLava) delta -= 0.05f;
|
||||||
if (!isMounted && underWater) delta -= 0.04f;
|
if (!isMounted && underWater) delta -= 0.04f;
|
||||||
if (!isMounted && inWater && !underWater) delta -= 0.02f;
|
if (!isMounted && inWater && !underWater) delta -= 0.02f;
|
||||||
int light = player.level().getMaxLocalRawBrightness(player.blockPosition());
|
|
||||||
if (light <= 2) delta -= 0.10f;
|
if (light <= 2) delta -= 0.10f;
|
||||||
else if (light <= 5) delta -= 0.05f;
|
else if (light <= 5) delta -= 0.05f;
|
||||||
if (player.level().isThundering()) delta -= 0.06f;
|
if (player.level().isThundering()) delta -= 0.06f;
|
||||||
@@ -152,6 +155,12 @@ public class PlayerTickHandler {
|
|||||||
}
|
}
|
||||||
if (player.isSleepingLongEnough())
|
if (player.isSleepingLongEnough())
|
||||||
delta += 0.10f;
|
delta += 0.10f;
|
||||||
|
|
||||||
|
delta += getSurvivalSanityDelta(player, light);
|
||||||
|
delta += getStatusSanityDelta(player);
|
||||||
|
delta += getNearbyBlockSanityDelta(player);
|
||||||
|
delta += getWorldSanityDelta(player, light);
|
||||||
|
|
||||||
boolean isInsane = insanity > 0;
|
boolean isInsane = insanity > 0;
|
||||||
if (isInsane) {
|
if (isInsane) {
|
||||||
if (delta > 0) {
|
if (delta > 0) {
|
||||||
@@ -244,6 +253,110 @@ public class PlayerTickHandler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static float getSurvivalSanityDelta(Player player, int light) {
|
||||||
|
float delta = 0f;
|
||||||
|
float healthPercent = player.getHealth() / player.getMaxHealth();
|
||||||
|
int food = player.getFoodData().getFoodLevel();
|
||||||
|
|
||||||
|
if (healthPercent <= 0.25f) delta -= 0.12f;
|
||||||
|
else if (healthPercent <= 0.50f) delta -= 0.06f;
|
||||||
|
|
||||||
|
if (player.isOnFire()) delta -= 0.12f;
|
||||||
|
if (player.isFreezing()) delta -= 0.08f;
|
||||||
|
if (player.getAirSupply() < player.getMaxAirSupply() / 2) delta -= 0.08f;
|
||||||
|
if (player.fallDistance > 6f) delta -= 0.06f;
|
||||||
|
if (player.isSprinting() && food <= 8) delta -= 0.03f;
|
||||||
|
|
||||||
|
if (healthPercent >= 0.95f && food >= 18 && light >= 10) delta += 0.04f;
|
||||||
|
if (player.isShiftKeyDown() && !player.isSprinting() && !player.isInWater() && light >= 8) delta += 0.015f;
|
||||||
|
if (player.getAbsorptionAmount() > 0f) delta += 0.03f;
|
||||||
|
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float getStatusSanityDelta(Player player) {
|
||||||
|
float delta = 0f;
|
||||||
|
|
||||||
|
if (player.hasEffect(MobEffects.POISON)) delta -= 0.08f;
|
||||||
|
if (player.hasEffect(MobEffects.WITHER)) delta -= 0.12f;
|
||||||
|
if (player.hasEffect(MobEffects.HUNGER)) delta -= 0.06f;
|
||||||
|
if (player.hasEffect(MobEffects.WEAKNESS)) delta -= 0.04f;
|
||||||
|
if (player.hasEffect(MobEffects.BLINDNESS)) delta -= 0.08f;
|
||||||
|
if (player.hasEffect(MobEffects.DARKNESS)) delta -= 0.12f;
|
||||||
|
if (player.hasEffect(MobEffects.CONFUSION)) delta -= 0.05f;
|
||||||
|
if (player.hasEffect(MobEffects.BAD_OMEN)) delta -= 0.04f;
|
||||||
|
|
||||||
|
if (player.hasEffect(MobEffects.REGENERATION)) delta += 0.06f;
|
||||||
|
if (player.hasEffect(MobEffects.DAMAGE_RESISTANCE)) delta += 0.04f;
|
||||||
|
if (player.hasEffect(MobEffects.ABSORPTION)) delta += 0.04f;
|
||||||
|
if (player.hasEffect(MobEffects.SATURATION)) delta += 0.05f;
|
||||||
|
if (player.hasEffect(MobEffects.HERO_OF_THE_VILLAGE)) delta += 0.08f;
|
||||||
|
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float getNearbyBlockSanityDelta(Player player) {
|
||||||
|
int comfortBlocks = 0;
|
||||||
|
int unsettlingBlocks = 0;
|
||||||
|
|
||||||
|
BlockPos center = player.blockPosition();
|
||||||
|
for (BlockPos pos : BlockPos.betweenClosed(center.offset(-4, -2, -4), center.offset(4, 3, 4))) {
|
||||||
|
var state = player.level().getBlockState(pos);
|
||||||
|
|
||||||
|
if (state.is(BlockTags.BEDS)
|
||||||
|
|| state.is(BlockTags.CANDLES)
|
||||||
|
|| state.is(BlockTags.FLOWERS)
|
||||||
|
|| state.is(Blocks.BOOKSHELF)
|
||||||
|
|| state.is(Blocks.CHISELED_BOOKSHELF)
|
||||||
|
|| state.is(Blocks.CAMPFIRE)
|
||||||
|
|| state.is(Blocks.LANTERN)
|
||||||
|
|| state.is(Blocks.SEA_LANTERN)) {
|
||||||
|
comfortBlocks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.is(Blocks.SOUL_FIRE)
|
||||||
|
|| state.is(Blocks.SOUL_CAMPFIRE)
|
||||||
|
|| state.is(Blocks.SOUL_LANTERN)
|
||||||
|
|| state.is(Blocks.SCULK)
|
||||||
|
|| state.is(Blocks.SCULK_SENSOR)
|
||||||
|
|| state.is(Blocks.SCULK_SHRIEKER)
|
||||||
|
|| state.is(Blocks.SCULK_CATALYST)
|
||||||
|
|| state.is(Blocks.COBWEB)
|
||||||
|
|| state.is(Blocks.WITHER_ROSE)
|
||||||
|
|| state.is(Blocks.NETHER_PORTAL)) {
|
||||||
|
unsettlingBlocks++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float comfort = Math.min(0.10f, comfortBlocks * 0.008f);
|
||||||
|
float unsettling = Math.min(0.16f, unsettlingBlocks * 0.012f);
|
||||||
|
return comfort - unsettling;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float getWorldSanityDelta(Player player, int light) {
|
||||||
|
float delta = 0f;
|
||||||
|
|
||||||
|
if (player.level().canSeeSky(player.blockPosition()) && player.level().isDay() && light >= 12 && !player.level().isRaining()) {
|
||||||
|
delta += 0.05f;
|
||||||
|
}
|
||||||
|
if (!player.level().canSeeSky(player.blockPosition()) && player.getY() < player.level().getSeaLevel() - 24) {
|
||||||
|
delta -= 0.06f;
|
||||||
|
}
|
||||||
|
if (player.level().getMoonBrightness() > 0.85f && !player.level().isDay() && player.level().canSeeSky(player.blockPosition())) {
|
||||||
|
delta -= 0.03f;
|
||||||
|
}
|
||||||
|
if (player.level().getBiome(player.blockPosition()).is(BiomeTags.IS_OCEAN) && !player.onGround()) {
|
||||||
|
delta -= 0.03f;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lastCombat = lastCombatTick.getOrDefault(player.getUUID(), -10000);
|
||||||
|
int ticksSinceCombat = player.tickCount - lastCombat;
|
||||||
|
if (ticksSinceCombat <= 80) delta -= 0.04f;
|
||||||
|
else if (ticksSinceCombat >= 20 * 60 && player.level().dimension() == net.minecraft.world.level.Level.OVERWORLD) delta += 0.025f;
|
||||||
|
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
private static void applySanityGameplayPressure(Player player, float sanityPercent, float insanityPercent) {
|
private static void applySanityGameplayPressure(Player player, float sanityPercent, float insanityPercent) {
|
||||||
float lowSanity = clamp01((55f - sanityPercent) / 55f);
|
float lowSanity = clamp01((55f - sanityPercent) / 55f);
|
||||||
float highInsanity = clamp01((insanityPercent - 35f) / 65f);
|
float highInsanity = clamp01((insanityPercent - 35f) / 65f);
|
||||||
|
|||||||
Reference in New Issue
Block a user