small changes
All checks were successful
Build Minecraft Mod / build (push) Successful in 6m18s
Build Minecraft Mod / release (push) Successful in 25s

This commit is contained in:
2026-04-17 13:11:54 +02:00
parent 33e2ae6d02
commit d541e69ed3
2 changed files with 96 additions and 14 deletions

View File

@@ -6,7 +6,7 @@ minecraft_version=1.20.1
yarn_mappings=1.20.1+build.10 yarn_mappings=1.20.1+build.10
loader_version=0.18.3 loader_version=0.18.3
# Mod Properties # Mod Properties
mod_version=26.4.16 mod_version=26.4.17
maven_group=dev.tggamesyt maven_group=dev.tggamesyt
archives_base_name=szar archives_base_name=szar
# Dependencies # Dependencies

View File

@@ -50,6 +50,7 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.*; import net.minecraft.item.*;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.registry.*; import net.minecraft.registry.*;
import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.registry.tag.BiomeTags; import net.minecraft.registry.tag.BiomeTags;
@@ -1466,23 +1467,36 @@ public class Szar implements ModInitializer {
ServerLivingEntityEvents.ALLOW_DAMAGE.register((entity, source, amount) -> { ServerLivingEntityEvents.ALLOW_DAMAGE.register((entity, source, amount) -> {
if (!(entity instanceof PlayerEntity player)) return true; if (!(entity instanceof PlayerEntity player)) return true;
// Check if wearing full Ender armor (optional — remove if you want any piece to trigger) int piecesWorn = 0;
boolean wearingFullSet = if (player.getInventory().getArmorStack(0).isOf(ENDER_BOOTS)) piecesWorn++;
player.getInventory().getArmorStack(0).isOf(ENDER_BOOTS) && if (player.getInventory().getArmorStack(1).isOf(ENDER_LEGGINGS)) piecesWorn++;
player.getInventory().getArmorStack(1).isOf(ENDER_LEGGINGS) && if (player.getInventory().getArmorStack(2).isOf(ENDER_CHESTPLATE)) piecesWorn++;
player.getInventory().getArmorStack(2).isOf(ENDER_CHESTPLATE) && if (player.getInventory().getArmorStack(3).isOf(ENDER_HELMET)) piecesWorn++;
player.getInventory().getArmorStack(3).isOf(ENDER_HELMET);
if (!wearingFullSet) return true; if (piecesWorn == 0) return true;
if (player.getHealth() > 4.0F) return true;
// If player would drop to <= 1 heart (2 HP) // armorFactor: 1 piece = 0.25, 2 = 0.5, 3 = 0.75, 4 = 1.0
if (player.getHealth() - amount <= 2.0F) { float armorFactor = piecesWorn / 4.0F;
if (player.getWorld() instanceof ServerWorld world) { // healthFactor: 4 HP (2 hearts) = 0.0, 0.5 HP (quarter heart) = ~0.875, 0 HP = 1.0
teleportRandomly(player, world); // Never reaches 1.0 in practice since player is alive
float healthFactor = 1.0F - (player.getHealth() / 4.0F);
// Combined: ranges from ~1% (1 piece, 2 hearts) to 75% (full set, half heart)
// Formula: 0.75 * armorFactor * healthFactor
// Full set half heart (0.5 HP): 0.75 * 1.0 * 0.875 = 65.6%
// Full set 1 HP: 0.75 * 1.0 * 0.75 = 56.3%
// 1 piece 4 HP: 0.75 * 0.25 * 0.0 = 0%
// 1 piece 3.5 HP: 0.75 * 0.25 * 0.125 = 2.3%
float chance = 0.75F * armorFactor * healthFactor;
if (chance <= 0F || player.getRandom().nextFloat() > chance) return true;
if (player.getWorld() instanceof ServerWorld world) {
if (teleportRandomlySafe(player, world)) {
return false;
} }
return false; // CANCEL DAMAGE
} }
return true; return true;
@@ -1549,6 +1563,74 @@ public class Szar implements ModInitializer {
} }
}); });
} }
private static boolean teleportRandomlySafe(PlayerEntity player, ServerWorld world) {
double origX = player.getX();
double origY = player.getY();
double origZ = player.getZ();
for (int attempt = 0; attempt < 32; attempt++) {
double x = origX + (player.getRandom().nextDouble() - 0.5) * 32.0;
double z = origZ + (player.getRandom().nextDouble() - 0.5) * 32.0;
// Find solid ground: start from player Y + 16, scan down
int startY = Math.min((int) origY + 16, world.getTopY() - 1);
BlockPos.Mutable mutable = new BlockPos.Mutable((int) x, startY, (int) z);
boolean foundGround = false;
for (int y = startY; y >= world.getBottomY() + 1; y--) {
mutable.setY(y);
BlockState below = world.getBlockState(mutable.down());
BlockState atFeet = world.getBlockState(mutable);
BlockState atHead = world.getBlockState(mutable.up());
// Ground must be solid + walkable, feet & head must be passable
if (below.isSolidBlock(world, mutable.down())
&& !below.isOf(Blocks.LAVA) && !below.isOf(Blocks.MAGMA_BLOCK)
&& !below.isOf(Blocks.CACTUS) && !below.isOf(Blocks.SWEET_BERRY_BUSH)
&& !atFeet.isSolidBlock(world, mutable)
&& !atFeet.isLiquid()
&& !atHead.isSolidBlock(world, mutable.up())
&& !atHead.isLiquid()) {
foundGround = true;
break;
}
}
if (!foundGround) continue;
double destX = mutable.getX() + 0.5;
double destY = mutable.getY();
double destZ = mutable.getZ() + 0.5;
// Particles at origin
world.spawnParticles(ParticleTypes.PORTAL, origX, origY + 1, origZ, 32,
0.5, 1.0, 0.5, 0.5);
// Sound at origin
world.playSound(null, origX, origY, origZ,
SoundEvents.ITEM_CHORUS_FRUIT_TELEPORT, SoundCategory.PLAYERS,
1.0F, 1.0F);
// Teleport
player.teleport(destX, destY, destZ);
// Particles at destination
world.spawnParticles(ParticleTypes.PORTAL, destX, destY + 1, destZ, 32,
0.5, 1.0, 0.5, 0.5);
world.spawnParticles(ParticleTypes.REVERSE_PORTAL, destX, destY + 1, destZ, 16,
0.3, 0.5, 0.3, 0.1);
// Sound at destination
world.playSound(null, destX, destY, destZ,
SoundEvents.ENTITY_ENDERMAN_TELEPORT, SoundCategory.PLAYERS,
1.0F, 1.0F);
return true;
}
return false; // all 32 attempts failed, no safe spot found
}
public static final Block SUPER_BEACON_BLOCK = new SuperBeaconBlock( public static final Block SUPER_BEACON_BLOCK = new SuperBeaconBlock(
FabricBlockSettings.copyOf(Blocks.BEACON).luminance(15) FabricBlockSettings.copyOf(Blocks.BEACON).luminance(15)
); );