Make sanity more intense
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
package net.fretux.mindmotion;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.fretux.mindmotion.command.SanityCommand;
|
||||
import net.fretux.mindmotion.event.CombatEvents;
|
||||
import net.fretux.mindmotion.event.PlayerTickHandler;
|
||||
import net.fretux.mindmotion.network.ModMessages;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.RegisterCommandsEvent;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
@@ -19,6 +22,7 @@ public class AscendMindMotion {
|
||||
public AscendMindMotion() {
|
||||
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
modEventBus.addListener(this::commonSetup);
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
MinecraftForge.EVENT_BUS.register(PlayerTickHandler.class);
|
||||
MinecraftForge.EVENT_BUS.register(CombatEvents.class);
|
||||
LOGGER.info("Ascend: Mind and Motion initialized!");
|
||||
@@ -27,4 +31,9 @@ public class AscendMindMotion {
|
||||
private void commonSetup(final FMLCommonSetupEvent event) {
|
||||
ModMessages.register();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerCommands(RegisterCommandsEvent event) {
|
||||
SanityCommand.register(event.getDispatcher());
|
||||
}
|
||||
}
|
||||
@@ -41,16 +41,10 @@ public class SanityTempoOverlay {
|
||||
int insanityFill = (int) (BAR_WIDTH * insanityPercent);
|
||||
|
||||
RenderSystem.enableBlend();
|
||||
|
||||
// --- TEMPO BAR ---
|
||||
drawRoundedBar(gui, xTempo, y, BAR_WIDTH, BAR_HEIGHT, 0xFF33AFFF, tempoFill);
|
||||
gui.drawString(mc.font, Component.literal("Tempo"), xTempo, y - 10, 0x66CCFF, false);
|
||||
|
||||
// --- SANITY OR INSANITY BAR ---
|
||||
boolean insaneMode = sanity <= 0;
|
||||
|
||||
if (!insaneMode) {
|
||||
// Normal sanity bar
|
||||
drawRoundedBar(gui, xSanity, y, BAR_WIDTH, BAR_HEIGHT, 0xFFFFFFFF, sanityFill);
|
||||
gui.drawString(mc.font, Component.literal("Sanity"), xSanity + BAR_WIDTH - 30, y - 10, 0xFFFFFF, false);
|
||||
} else {
|
||||
|
||||
@@ -93,15 +93,25 @@ public class SanityShaderHandler {
|
||||
float blur = 0f;
|
||||
float vig = 0f;
|
||||
float fog = 0f;
|
||||
|
||||
float flash = 0f;
|
||||
if (sanityPct < 0.5f) {
|
||||
blur = (0.5f - sanityPct) * 0.6f;
|
||||
vig = (0.5f - sanityPct) * 0.4f;
|
||||
fog = (0.5f - sanityPct) * 0.25f;
|
||||
blur = (0.5f - sanityPct) * 0.6f;
|
||||
vig = (0.5f - sanityPct) * 0.4f;
|
||||
fog = (0.5f - sanityPct) * 0.25f;
|
||||
}
|
||||
blur += insanityPct * 0.25f;
|
||||
vig += insanityPct * 0.35f;
|
||||
fog += insanityPct * 0.35f;
|
||||
if (insanityPct >= 0.8f) {
|
||||
float level = (insanityPct - 0.8f) / 0.2f;
|
||||
flash = 0.5f * level;
|
||||
if (mc.player.getRandom().nextFloat() < 0.01f) {
|
||||
flash += 0.4f;
|
||||
}
|
||||
flash = Math.min(flash, 1f);
|
||||
}
|
||||
var uFlash = effect.getUniform("FlashStrength");
|
||||
if (uFlash != null) uFlash.set(flash);
|
||||
blur += insanityPct * 0.25f;
|
||||
vig += insanityPct * 0.35f;
|
||||
fog += insanityPct * 0.35f;
|
||||
blur = Math.min(blur, 1f);
|
||||
vig = Math.min(vig, 1f);
|
||||
fog = Math.min(fog, 1f);
|
||||
@@ -114,6 +124,24 @@ public class SanityShaderHandler {
|
||||
|
||||
var uFog = effect.getUniform("FogStrength");
|
||||
if (uFog != null) uFog.set(fog);
|
||||
float shake = 0f;
|
||||
float pulse = 0f;
|
||||
if (sanityPct <= 0.125f) {
|
||||
float lowSan = (0.125f - sanityPct) / 0.125f;
|
||||
shake = lowSan * 0.010f;
|
||||
pulse = lowSan * 0.6f;
|
||||
}
|
||||
shake += insanityPct * 0.012f;
|
||||
pulse += insanityPct * 0.8f;
|
||||
shake = Math.min(shake, 0.025f);
|
||||
pulse = Math.min(pulse, 1f);
|
||||
var uShake = effect.getUniform("ShakeStrength");
|
||||
if (uShake != null) uShake.set(shake);
|
||||
var uPulse = effect.getUniform("PulseStrength");
|
||||
if (uPulse != null) uPulse.set(pulse);
|
||||
float time = (mc.level.getGameTime() % 200000) / 20f;
|
||||
var uTime = effect.getUniform("Time");
|
||||
if (uTime != null) uTime.set(time);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package net.fretux.mindmotion.command;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.arguments.FloatArgumentType;
|
||||
import net.fretux.mindmotion.player.PlayerCapabilityProvider;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.Commands;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
public class SanityCommand {
|
||||
|
||||
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
|
||||
dispatcher.register(Commands.literal("sanity")
|
||||
.requires(source -> source.hasPermission(2)) // OP only
|
||||
.then(Commands.literal("set")
|
||||
.then(Commands.argument("sanity", FloatArgumentType.floatArg(0, 80))
|
||||
.then(Commands.argument("insanity", FloatArgumentType.floatArg(0, 80))
|
||||
.executes(ctx -> {
|
||||
ServerPlayer player = ctx.getSource().getPlayer();
|
||||
float sanity = FloatArgumentType.getFloat(ctx, "sanity");
|
||||
float insanity = FloatArgumentType.getFloat(ctx, "insanity");
|
||||
|
||||
player.getCapability(PlayerCapabilityProvider.SANITY).ifPresent(cap -> {
|
||||
cap.setSanity(sanity);
|
||||
cap.setInsanity(insanity);
|
||||
});
|
||||
|
||||
ctx.getSource().sendSuccess(() ->
|
||||
net.minecraft.network.chat.Component.literal(
|
||||
"Set sanity = " + sanity + ", insanity = " + insanity),
|
||||
true
|
||||
);
|
||||
|
||||
return 1;
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import net.fretux.mindmotion.network.ModMessages;
|
||||
import net.fretux.mindmotion.network.SyncStatsS2CPacket;
|
||||
import net.fretux.mindmotion.player.PlayerCapabilityProvider;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.tags.BiomeTags;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -23,6 +24,8 @@ public class PlayerTickHandler {
|
||||
private static final int TEMPO_TICK_INTERVAL = 15;
|
||||
private static final int COMBAT_DECAY_DELAY = 100;
|
||||
private static final Map<UUID, Integer> lastCombatTick = new ConcurrentHashMap<>();
|
||||
private static final Map<UUID, Integer> insanityDamageTicks = new ConcurrentHashMap<>();
|
||||
private static final Map<UUID, Integer> lowSanitySoundCooldown = new ConcurrentHashMap<>();
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
|
||||
@@ -58,7 +61,7 @@ public class PlayerTickHandler {
|
||||
float value = sanity.getSanity();
|
||||
float insanity = sanity.getInsanity();
|
||||
float delta = 0f;
|
||||
boolean inDark = player.level().getMaxLocalRawBrightness(player.blockPosition()) < 5;
|
||||
boolean inDark = player.level().getMaxLocalRawBrightness(player.blockPosition()) < 8;
|
||||
boolean inRain = player.level().isRainingAt(player.blockPosition());
|
||||
boolean isHungry = player.getFoodData().getFoodLevel() < 6;
|
||||
boolean nearLava = player.level().getBlockState(player.blockPosition().below()).is(Blocks.LAVA);
|
||||
@@ -67,26 +70,85 @@ public class PlayerTickHandler {
|
||||
boolean sleeping = player.isSleeping();
|
||||
boolean inLight = player.level().getMaxLocalRawBrightness(player.blockPosition()) > 12;
|
||||
boolean nearTorch = player.level().getBlockState(player.blockPosition().above()).is(Blocks.TORCH);
|
||||
if (inDark) delta -= 2f;
|
||||
if (inDark) delta -= 0.02f;
|
||||
if (inRain) delta -= 0.04f;
|
||||
if (isHungry) delta -= 0.06f;
|
||||
if (nearLava) delta -= 0.05f;
|
||||
if (underWater) delta -= 0.04f;
|
||||
if (inWater && !underWater) delta -= 0.02f;
|
||||
int light = player.level().getMaxLocalRawBrightness(player.blockPosition());
|
||||
if (light <= 2) delta -= 0.10f;
|
||||
else if (light <= 5) delta -= 0.05f;
|
||||
if (player.level().isThundering()) delta -= 0.06f;
|
||||
if (player.level().getBiome(player.blockPosition())
|
||||
.is(BiomeTags.IS_END)) {
|
||||
delta -= 0.02f;
|
||||
}
|
||||
if (player.level().getBiome(player.blockPosition())
|
||||
.is(BiomeTags.IS_NETHER)) {
|
||||
delta -= 0.015f;
|
||||
}
|
||||
if (player.level().dimension() == net.minecraft.world.level.Level.NETHER)
|
||||
delta -= 0.12f;
|
||||
if (player.level().dimension() == net.minecraft.world.level.Level.END)
|
||||
delta -= 0.08f;
|
||||
if (!player.level().getEntities(player, player.getBoundingBox().inflate(30),
|
||||
e -> e.getType().toString().contains("warden")).isEmpty()) {
|
||||
delta -= 0.15f;
|
||||
}
|
||||
long hostileCount = player.level().getEntities(player,
|
||||
player.getBoundingBox().inflate(10),
|
||||
e -> e instanceof net.minecraft.world.entity.Mob && !(e instanceof net.minecraft.world.entity.animal.Animal)
|
||||
).size();
|
||||
delta -= hostileCount * 0.005f;
|
||||
if (inLight) delta += 0.03f;
|
||||
if (nearTorch) delta += 0.05f;
|
||||
if (sleeping) delta += 0.25f;
|
||||
if (player.getUseItem() != null && player.getUseItem().isEdible()) delta += 0.05f;
|
||||
if (player.level().getBlockState(player.blockPosition().below())
|
||||
.is(net.minecraft.world.level.block.Blocks.CAMPFIRE)) {
|
||||
delta += 0.08f;
|
||||
}
|
||||
if (player.level().getBlockState(player.blockPosition().below())
|
||||
.is(Blocks.FURNACE) || (player.level().getBlockState(player.blockPosition().below())
|
||||
.is(Blocks.BLAST_FURNACE)) || (player.level().getBlockState(player.blockPosition().below())
|
||||
.is(Blocks.SMOKER))) {
|
||||
delta += 0.04f;
|
||||
}
|
||||
long animalCount = player.level().getEntities(player,
|
||||
player.getBoundingBox().inflate(6),
|
||||
e -> e instanceof net.minecraft.world.entity.animal.Animal
|
||||
).size();
|
||||
delta += animalCount * 0.01f;
|
||||
long villagerCount = player.level().getEntities(player,
|
||||
player.getBoundingBox().inflate(8),
|
||||
e -> e instanceof net.minecraft.world.entity.npc.Villager
|
||||
).size();
|
||||
delta += villagerCount * 0.02f;
|
||||
if (player.level().getBlockState(player.blockPosition().below()).is(Blocks.BEACON))
|
||||
delta += 0.15f;
|
||||
if (player.getMainHandItem().is(Blocks.POPPY.asItem())
|
||||
|| player.getMainHandItem().is(Blocks.DANDELION.asItem())) {
|
||||
delta += 0.04f;
|
||||
}
|
||||
if (player.isSleepingLongEnough())
|
||||
delta += 0.10f;
|
||||
sanity.setSanity(value + delta);
|
||||
if (sanity.getSanity() <= 0) {
|
||||
sanity.setSanity(0);
|
||||
if (sanity.getSanity() > 0) {
|
||||
sanity.setInsanity(Math.max(0, insanity - 0.15f));
|
||||
insanityDamageTicks.remove(player.getUUID());
|
||||
} else {
|
||||
sanity.setInsanity(Math.min(sanity.getMaxSanity(), insanity + 0.3f));
|
||||
if (sanity.getInsanity() >= sanity.getMaxSanity()) {
|
||||
player.kill();
|
||||
UUID id = player.getUUID();
|
||||
int ticks = insanityDamageTicks.getOrDefault(id, 0) + SANITY_TICK_INTERVAL;
|
||||
insanityDamageTicks.put(id, ticks);
|
||||
|
||||
float damage = 1.0f + (ticks / 100f);
|
||||
player.hurt(player.damageSources().magic(), damage);
|
||||
player.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 40, 1));
|
||||
return;
|
||||
}
|
||||
} else if (sanity.getInsanity() > 0) {
|
||||
sanity.setInsanity(Math.max(0, insanity - 0.15f));
|
||||
}
|
||||
float percent = (value / sanity.getMaxSanity()) * 100f;
|
||||
if (percent <= 70 && Math.random() < 0.03) {
|
||||
@@ -107,6 +169,17 @@ public class PlayerTickHandler {
|
||||
applyScratching(player);
|
||||
}
|
||||
}
|
||||
if (percent <= 30f) {
|
||||
UUID id = player.getUUID();
|
||||
int cd = lowSanitySoundCooldown.getOrDefault(id, 0) - SANITY_TICK_INTERVAL;
|
||||
if (cd <= 0) {
|
||||
playSanitySound(player);
|
||||
cd = 20 * (6 + player.getRandom().nextInt(15));
|
||||
}
|
||||
lowSanitySoundCooldown.put(id, cd);
|
||||
} else {
|
||||
lowSanitySoundCooldown.remove(player.getUUID());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -141,4 +214,38 @@ public class PlayerTickHandler {
|
||||
player.hurt(player.damageSources().magic(), 2f);
|
||||
applyShiver(player);
|
||||
}
|
||||
|
||||
private static void playSanitySound(Player player) {
|
||||
var level = player.level();
|
||||
if (level.isClientSide) return;
|
||||
var sounds = new net.minecraft.sounds.SoundEvent[]{
|
||||
net.minecraft.sounds.SoundEvents.ZOMBIE_AMBIENT,
|
||||
net.minecraft.sounds.SoundEvents.ENDERMAN_STARE,
|
||||
net.minecraft.sounds.SoundEvents.SPIDER_AMBIENT,
|
||||
net.minecraft.sounds.SoundEvents.CREEPER_PRIMED,
|
||||
net.minecraft.sounds.SoundEvents.HUSK_AMBIENT,
|
||||
net.minecraft.sounds.SoundEvents.WARDEN_ANGRY
|
||||
};
|
||||
net.minecraft.sounds.SoundEvent chosen =
|
||||
sounds[player.getRandom().nextInt(sounds.length)];
|
||||
var holder = net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT.wrapAsHolder(chosen);
|
||||
float yaw = player.getYRot();
|
||||
double angleRad = Math.toRadians(yaw + 180 + player.getRandom().nextInt(40) - 20);
|
||||
double dist = 4.0 + player.getRandom().nextDouble() * 3.0;
|
||||
double dx = player.getX() + Math.cos(angleRad) * dist;
|
||||
double dz = player.getZ() + Math.sin(angleRad) * dist;
|
||||
double dy = player.getY();
|
||||
if (player instanceof ServerPlayer sp) {
|
||||
sp.connection.send(
|
||||
new net.minecraft.network.protocol.game.ClientboundSoundPacket(
|
||||
holder,
|
||||
net.minecraft.sounds.SoundSource.AMBIENT,
|
||||
dx, dy, dz,
|
||||
1.0f,
|
||||
0.9f + player.getRandom().nextFloat() * 0.2f,
|
||||
player.getRandom().nextLong()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user