experimental popups fix and beer extension
This commit is contained in:
@@ -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.3.20
|
mod_version=26.3.21
|
||||||
maven_group=dev.tggamesyt
|
maven_group=dev.tggamesyt
|
||||||
archives_base_name=szar
|
archives_base_name=szar
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
|||||||
@@ -21,8 +21,11 @@ import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.lit
|
|||||||
public class PanoramaClientCommand {
|
public class PanoramaClientCommand {
|
||||||
|
|
||||||
static void register(CommandDispatcher<FabricClientCommandSource> dispatcher) {
|
static void register(CommandDispatcher<FabricClientCommandSource> dispatcher) {
|
||||||
dispatcher.register(literal("takepanorama")
|
dispatcher.register(
|
||||||
.executes(PanoramaClientCommand::execute));
|
literal("szar")
|
||||||
|
.then(literal("takepanorama")
|
||||||
|
.executes(PanoramaClientCommand::execute))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int execute(CommandContext<FabricClientCommandSource> context) {
|
private static int execute(CommandContext<FabricClientCommandSource> context) {
|
||||||
|
|||||||
@@ -93,6 +93,10 @@ public class SzarClient implements ClientModInitializer {
|
|||||||
);
|
);
|
||||||
@Override
|
@Override
|
||||||
public void onInitializeClient() {
|
public void onInitializeClient() {
|
||||||
|
ClientPlayNetworking.registerGlobalReceiver(Szar.DRUNK_TYPE_PACKET, (client, handler, buf, responseSender) -> {
|
||||||
|
String typeName = buf.readString();
|
||||||
|
client.execute(() -> DrunkEffect.setDisplayType(typeName));
|
||||||
|
});
|
||||||
SmilerEffectRenderer.register();
|
SmilerEffectRenderer.register();
|
||||||
EntityRendererRegistry.register(Szar.SMILER_ENTITY_TYPE, SmilerRenderer::new);
|
EntityRendererRegistry.register(Szar.SMILER_ENTITY_TYPE, SmilerRenderer::new);
|
||||||
ClientPlayNetworking.registerGlobalReceiver(OPEN_DETONATOR_SCREEN, (client, handler, buf, responseSender) -> {
|
ClientPlayNetworking.registerGlobalReceiver(OPEN_DETONATOR_SCREEN, (client, handler, buf, responseSender) -> {
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package dev.tggamesyt.szar.client.mixin;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Lifecycle;
|
||||||
|
import net.minecraft.client.gui.screen.world.CreateWorldScreen;
|
||||||
|
import net.minecraft.client.world.GeneratorOptionsHolder;
|
||||||
|
import net.minecraft.world.gen.GeneratorOptions;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
|
@Mixin(CreateWorldScreen.class)
|
||||||
|
public class CreateWorldScreenMixin {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forces bypassWarnings=true on the tryLoad call inside createLevel(),
|
||||||
|
* so the experimental/deprecated world warning is never shown.
|
||||||
|
* The 5th parameter (index 4) of tryLoad is the boolean bypassWarnings.
|
||||||
|
*/
|
||||||
|
@ModifyArg(
|
||||||
|
method = "createLevel",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/server/integrated/IntegratedServerLoader;tryLoad(Lnet/minecraft/client/MinecraftClient;Lnet/minecraft/client/gui/screen/world/CreateWorldScreen;Lcom/mojang/serialization/Lifecycle;Ljava/lang/Runnable;Z)V"
|
||||||
|
),
|
||||||
|
index = 4
|
||||||
|
)
|
||||||
|
private boolean forceBypassWarnings(boolean original) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package dev.tggamesyt.szar.client.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
import net.minecraft.server.integrated.IntegratedServerLoader;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(IntegratedServerLoader.class)
|
||||||
|
public class IntegratedServerLoaderMixin {
|
||||||
|
|
||||||
|
@Final
|
||||||
|
@Shadow
|
||||||
|
private MinecraftClient client;
|
||||||
|
|
||||||
|
@Inject(
|
||||||
|
method = "showBackupPromptScreen",
|
||||||
|
at = @At("HEAD"),
|
||||||
|
cancellable = true
|
||||||
|
)
|
||||||
|
private void skipBackupPrompt(
|
||||||
|
Screen parent,
|
||||||
|
String levelName,
|
||||||
|
boolean customized,
|
||||||
|
Runnable callback,
|
||||||
|
CallbackInfo ci) {
|
||||||
|
this.client.send(callback);
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,9 +5,11 @@
|
|||||||
"compatibilityLevel": "JAVA_17",
|
"compatibilityLevel": "JAVA_17",
|
||||||
"client": [
|
"client": [
|
||||||
"BipedEntityModelMixin",
|
"BipedEntityModelMixin",
|
||||||
|
"CreateWorldScreenMixin",
|
||||||
"EntityRenderMixin",
|
"EntityRenderMixin",
|
||||||
"GameRendererMixin",
|
"GameRendererMixin",
|
||||||
"HeldItemRendererMixin",
|
"HeldItemRendererMixin",
|
||||||
|
"IntegratedServerLoaderMixin",
|
||||||
"ItemRendererMixin",
|
"ItemRendererMixin",
|
||||||
"LogoDrawerMixin",
|
"LogoDrawerMixin",
|
||||||
"MouseFlipMixin",
|
"MouseFlipMixin",
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class BackroomsBarrelManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void tick(MinecraftServer server) {
|
private static void tick(MinecraftServer server) {
|
||||||
ServerWorld backrooms = server.getWorld(Szar.BACKROOMS_KEY);
|
ServerWorld backrooms = server.getWorld(Szar.BACKROOMS_LEVEL_KEY);
|
||||||
if (backrooms == null) return;
|
if (backrooms == null) return;
|
||||||
|
|
||||||
List<ServerPlayerEntity> players = backrooms.getPlayers();
|
List<ServerPlayerEntity> players = backrooms.getPlayers();
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class BackroomsLightManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void tick(MinecraftServer server) {
|
private static void tick(MinecraftServer server) {
|
||||||
ServerWorld backrooms = server.getWorld(Szar.BACKROOMS_KEY);
|
ServerWorld backrooms = server.getWorld(Szar.BACKROOMS_LEVEL_KEY);
|
||||||
if (backrooms == null) return;
|
if (backrooms == null) return;
|
||||||
|
|
||||||
globalFlickerTimer++;
|
globalFlickerTimer++;
|
||||||
|
|||||||
@@ -4,55 +4,209 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
|||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.effect.StatusEffect;
|
import net.minecraft.entity.effect.StatusEffect;
|
||||||
import net.minecraft.entity.effect.StatusEffectCategory;
|
import net.minecraft.entity.effect.StatusEffectCategory;
|
||||||
import net.minecraft.entity.effect.StatusEffectInstance;
|
import net.minecraft.entity.projectile.ProjectileUtil;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.network.packet.s2c.play.EntityAnimationS2CPacket;
|
import net.minecraft.network.packet.s2c.play.EntityAnimationS2CPacket;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.sound.SoundCategory;
|
||||||
|
import net.minecraft.sound.SoundEvents;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.hit.EntityHitResult;
|
import net.minecraft.util.hit.EntityHitResult;
|
||||||
import net.minecraft.util.hit.HitResult;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.RaycastContext;
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class DrunkEffect extends StatusEffect {
|
public class DrunkEffect extends StatusEffect {
|
||||||
|
|
||||||
|
public enum DrunkType { AGGRESSIVE, STUMBLING, SLEEPY, GENEROUS, PARANOID }
|
||||||
|
|
||||||
|
// Per-player assigned drunk type — assigned when effect is first detected
|
||||||
|
private static final Map<UUID, DrunkType> playerTypes = new HashMap<>();
|
||||||
|
// For sleepy — track how long the player is forced to crouch
|
||||||
|
private static final Map<UUID, Integer> sleepyTimer = new HashMap<>();
|
||||||
|
static String currentDisplayType = "None";
|
||||||
public DrunkEffect() {
|
public DrunkEffect() {
|
||||||
super(StatusEffectCategory.HARMFUL, 0xFF9900);
|
super(StatusEffectCategory.HARMFUL, 0xFF9900);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tick(MinecraftServer server) {
|
static void tick(MinecraftServer server) {
|
||||||
for (var world : server.getWorlds()) {
|
for (var world : server.getWorlds()) {
|
||||||
if (world.getTime() % 20 != 0) continue;
|
|
||||||
|
|
||||||
for (ServerPlayerEntity player : world.getPlayers()) {
|
for (ServerPlayerEntity player : world.getPlayers()) {
|
||||||
if (!player.hasStatusEffect(Szar.DRUNK_EFFECT)) continue;
|
if (!player.hasStatusEffect(Szar.DRUNK_EFFECT)) {
|
||||||
if (world.random.nextInt(5) >= 2) continue; // 2 in 5 chance
|
// Clean up when effect ends
|
||||||
|
playerTypes.remove(player.getUuid());
|
||||||
|
sleepyTimer.remove(player.getUuid());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
double reach = 4.5;
|
// Assign type if not yet assigned
|
||||||
net.minecraft.util.math.Vec3d eyePos = player.getEyePos();
|
DrunkType type = playerTypes.computeIfAbsent(player.getUuid(), k -> {
|
||||||
net.minecraft.util.math.Vec3d lookVec = player.getRotationVector();
|
DrunkType[] values = DrunkType.values();
|
||||||
net.minecraft.util.math.Vec3d endPos = eyePos.add(lookVec.multiply(reach));
|
DrunkType assigned = values[world.random.nextInt(values.length)];
|
||||||
|
|
||||||
EntityHitResult entityHit = net.minecraft.entity.projectile.ProjectileUtil
|
String typeName = assigned.name().charAt(0)
|
||||||
.getEntityCollision(
|
+ assigned.name().substring(1).toLowerCase();
|
||||||
world,
|
net.minecraft.network.PacketByteBuf buf =
|
||||||
player,
|
net.fabricmc.fabric.api.networking.v1.PacketByteBufs.create();
|
||||||
eyePos,
|
buf.writeString(typeName);
|
||||||
endPos,
|
net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking.send(
|
||||||
player.getBoundingBox().stretch(lookVec.multiply(reach)).expand(1.0),
|
player, Szar.DRUNK_TYPE_PACKET, buf);
|
||||||
e -> e instanceof LivingEntity && e != player && !e.isSpectator()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (entityHit == null) continue;
|
return assigned;
|
||||||
if (!(entityHit.getEntity() instanceof LivingEntity target)) continue;
|
});
|
||||||
|
|
||||||
player.attack(target);
|
switch (type) {
|
||||||
player.swingHand(net.minecraft.util.Hand.MAIN_HAND);
|
case AGGRESSIVE -> tickAggressive(world, player);
|
||||||
|
case STUMBLING -> tickStumbling(world, player);
|
||||||
EntityAnimationS2CPacket swingPacket =
|
case SLEEPY -> tickSleepy(world, player);
|
||||||
new EntityAnimationS2CPacket(
|
case GENEROUS -> tickGenerous(world, player);
|
||||||
player, 0); // 0 = swing main hand
|
case PARANOID -> tickParanoid(world, player);
|
||||||
player.networkHandler.sendPacket(swingPacket);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- AGGRESSIVE ---
|
||||||
|
private static void tickAggressive(net.minecraft.server.world.ServerWorld world,
|
||||||
|
ServerPlayerEntity player) {
|
||||||
|
if (world.getTime() % 20 != 0) return;
|
||||||
|
if (world.random.nextInt(5) >= 2) return;
|
||||||
|
|
||||||
|
Vec3d eyePos = player.getEyePos();
|
||||||
|
Vec3d lookVec = player.getRotationVector();
|
||||||
|
Vec3d endPos = eyePos.add(lookVec.multiply(4.5));
|
||||||
|
|
||||||
|
EntityHitResult hit = ProjectileUtil.getEntityCollision(
|
||||||
|
world, player, eyePos, endPos,
|
||||||
|
player.getBoundingBox().stretch(lookVec.multiply(4.5)).expand(1.0),
|
||||||
|
e -> e instanceof LivingEntity && e != player && !e.isSpectator()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hit == null) return;
|
||||||
|
if (!(hit.getEntity() instanceof LivingEntity target)) return;
|
||||||
|
|
||||||
|
player.attack(target);
|
||||||
|
player.swingHand(Hand.MAIN_HAND);
|
||||||
|
player.networkHandler.sendPacket(new EntityAnimationS2CPacket(player, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- STUMBLING ---
|
||||||
|
private static void tickStumbling(net.minecraft.server.world.ServerWorld world,
|
||||||
|
ServerPlayerEntity player) {
|
||||||
|
if (world.getTime() % 10 != 0) return;
|
||||||
|
if (world.random.nextInt(4) != 0) return;
|
||||||
|
|
||||||
|
// Add a random sideways velocity push
|
||||||
|
Vec3d current = player.getVelocity();
|
||||||
|
double pushX = (world.random.nextDouble() - 0.5) * 0.4;
|
||||||
|
double pushZ = (world.random.nextDouble() - 0.5) * 0.4;
|
||||||
|
player.setVelocity(current.x + pushX, current.y, current.z + pushZ);
|
||||||
|
player.velocityModified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- SLEEPY ---
|
||||||
|
private static void tickSleepy(net.minecraft.server.world.ServerWorld world,
|
||||||
|
ServerPlayerEntity player) {
|
||||||
|
UUID uuid = player.getUuid();
|
||||||
|
int timer = sleepyTimer.getOrDefault(uuid, 0);
|
||||||
|
|
||||||
|
if (timer > 0) {
|
||||||
|
// Force crouch and stop movement
|
||||||
|
player.setVelocity(0, player.getVelocity().y, 0);
|
||||||
|
player.velocityModified = true;
|
||||||
|
player.setSneaking(true);
|
||||||
|
sleepyTimer.put(uuid, timer - 1);
|
||||||
|
} else {
|
||||||
|
player.setSneaking(false);
|
||||||
|
// Every 3 seconds, 1 in 4 chance to fall asleep for 1-3 seconds
|
||||||
|
if (world.getTime() % 60 == 0 && world.random.nextInt(4) == 0) {
|
||||||
|
int sleepDuration = 20 + world.random.nextInt(40); // 1-3 seconds
|
||||||
|
sleepyTimer.put(uuid, sleepDuration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- GENEROUS ---
|
||||||
|
private static void tickGenerous(net.minecraft.server.world.ServerWorld world,
|
||||||
|
ServerPlayerEntity player) {
|
||||||
|
if (world.getTime() % 60 != 0) return; // every 3 seconds
|
||||||
|
if (world.random.nextInt(4) != 0) return;
|
||||||
|
|
||||||
|
// Find a random non-empty slot
|
||||||
|
var inv = player.getInventory();
|
||||||
|
java.util.List<Integer> nonEmpty = new java.util.ArrayList<>();
|
||||||
|
for (int i = 0; i < inv.size(); i++) {
|
||||||
|
if (!inv.getStack(i).isEmpty()) nonEmpty.add(i);
|
||||||
|
}
|
||||||
|
if (nonEmpty.isEmpty()) return;
|
||||||
|
|
||||||
|
int slot = nonEmpty.get(world.random.nextInt(nonEmpty.size()));
|
||||||
|
ItemStack stack = inv.getStack(slot);
|
||||||
|
|
||||||
|
// Drop one item from the stack
|
||||||
|
ItemStack toDrop = stack.copy();
|
||||||
|
toDrop.setCount(1);
|
||||||
|
stack.decrement(1);
|
||||||
|
if (stack.isEmpty()) inv.setStack(slot, ItemStack.EMPTY);
|
||||||
|
|
||||||
|
player.dropItem(toDrop, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- PARANOID ---
|
||||||
|
private static void tickParanoid(net.minecraft.server.world.ServerWorld world,
|
||||||
|
ServerPlayerEntity player) {
|
||||||
|
if (world.getTime() % 20 != 0) return;
|
||||||
|
if (world.random.nextInt(3) != 0) return;
|
||||||
|
|
||||||
|
// Play a footstep sound at a random position nearby
|
||||||
|
double offsetX = (world.random.nextDouble() - 0.5) * 10;
|
||||||
|
double offsetZ = (world.random.nextDouble() - 0.5) * 10;
|
||||||
|
double x = player.getX() + offsetX;
|
||||||
|
double y = player.getY();
|
||||||
|
double z = player.getZ() + offsetZ;
|
||||||
|
|
||||||
|
// Pick a random footstep sound
|
||||||
|
net.minecraft.sound.SoundEvent[] footsteps = {
|
||||||
|
SoundEvents.BLOCK_STONE_STEP,
|
||||||
|
SoundEvents.BLOCK_GRAVEL_STEP,
|
||||||
|
SoundEvents.BLOCK_WOOD_STEP,
|
||||||
|
SoundEvents.BLOCK_SAND_STEP
|
||||||
|
};
|
||||||
|
net.minecraft.sound.SoundEvent sound =
|
||||||
|
footsteps[world.random.nextInt(footsteps.length)];
|
||||||
|
|
||||||
|
// Play only to this player
|
||||||
|
player.networkHandler.sendPacket(
|
||||||
|
new net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket(
|
||||||
|
world.getRegistryManager()
|
||||||
|
.get(net.minecraft.registry.RegistryKeys.SOUND_EVENT)
|
||||||
|
.getEntry(sound),
|
||||||
|
SoundCategory.PLAYERS,
|
||||||
|
x, y, z,
|
||||||
|
0.8f + world.random.nextFloat() * 0.4f,
|
||||||
|
0.8f + world.random.nextFloat() * 0.4f,
|
||||||
|
world.random.nextLong()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Text getName() {
|
||||||
|
if (currentDisplayType.isEmpty()) return Text.literal("Drunk");
|
||||||
|
return Text.literal("Drunk ")
|
||||||
|
.append(Text.literal("(" + currentDisplayType + ")")
|
||||||
|
.formatted(net.minecraft.util.Formatting.GRAY));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setDisplayType(String typeName) {
|
||||||
|
currentDisplayType = typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void preAssignType(UUID uuid, DrunkType type) {
|
||||||
|
playerTypes.put(uuid, type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -5,17 +5,13 @@ import net.minecraft.block.BlockState;
|
|||||||
import net.minecraft.block.ShapeContext;
|
import net.minecraft.block.ShapeContext;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.ItemEntity;
|
import net.minecraft.entity.ItemEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
import net.minecraft.nbt.NbtList;
|
import net.minecraft.nbt.NbtList;
|
||||||
import net.minecraft.registry.RegistryKey;
|
|
||||||
import net.minecraft.registry.RegistryKeys;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
import net.minecraft.util.shape.VoxelShapes;
|
import net.minecraft.util.shape.VoxelShapes;
|
||||||
@@ -58,13 +54,13 @@ public class PortalBlock extends Block {
|
|||||||
// Full player handling — inventory save, tracker registration, etc.
|
// Full player handling — inventory save, tracker registration, etc.
|
||||||
if (world.getRegistryKey() == World.OVERWORLD) {
|
if (world.getRegistryKey() == World.OVERWORLD) {
|
||||||
teleportToNether(player, tracker, server, pos);
|
teleportToNether(player, tracker, server, pos);
|
||||||
} else if (world.getRegistryKey() == Szar.BACKROOMS_KEY) {
|
} else if (world.getRegistryKey() == Szar.BACKROOMS_LEVEL_KEY) {
|
||||||
teleportToOverworld(player, tracker, server);
|
teleportToOverworld(player, tracker, server);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Non-player entity — teleport only, no inventory or tracker registration
|
// Non-player entity — teleport only, no inventory or tracker registration
|
||||||
if (world.getRegistryKey() == World.OVERWORLD) {
|
if (world.getRegistryKey() == World.OVERWORLD) {
|
||||||
ServerWorld backrooms = server.getWorld(Szar.BACKROOMS_KEY);
|
ServerWorld backrooms = server.getWorld(Szar.BACKROOMS_LEVEL_KEY);
|
||||||
if (backrooms == null) return;
|
if (backrooms == null) return;
|
||||||
|
|
||||||
// Save overworld entry coords for this entity
|
// Save overworld entry coords for this entity
|
||||||
@@ -75,7 +71,7 @@ public class PortalBlock extends Block {
|
|||||||
entity.teleport(backrooms, entity.getX(), safeY, entity.getZ(),
|
entity.teleport(backrooms, entity.getX(), safeY, entity.getZ(),
|
||||||
java.util.Set.of(), entity.getYaw(), entity.getPitch());
|
java.util.Set.of(), entity.getYaw(), entity.getPitch());
|
||||||
|
|
||||||
} else if (world.getRegistryKey() == Szar.BACKROOMS_KEY) {
|
} else if (world.getRegistryKey() == Szar.BACKROOMS_LEVEL_KEY) {
|
||||||
ServerWorld overworld = server.getWorld(World.OVERWORLD);
|
ServerWorld overworld = server.getWorld(World.OVERWORLD);
|
||||||
if (overworld == null) return;
|
if (overworld == null) return;
|
||||||
|
|
||||||
@@ -134,7 +130,7 @@ public class PortalBlock extends Block {
|
|||||||
tracker.addPlayer(player.getUuid());
|
tracker.addPlayer(player.getUuid());
|
||||||
|
|
||||||
// Teleport
|
// Teleport
|
||||||
ServerWorld nether = server.getWorld(Szar.BACKROOMS_KEY);
|
ServerWorld nether = server.getWorld(Szar.BACKROOMS_LEVEL_KEY);
|
||||||
if (nether == null) return;
|
if (nether == null) return;
|
||||||
|
|
||||||
double netherX = player.getX();
|
double netherX = player.getX();
|
||||||
@@ -179,7 +175,7 @@ public class PortalBlock extends Block {
|
|||||||
netherTracker.removePlayer(player.getUuid());
|
netherTracker.removePlayer(player.getUuid());
|
||||||
|
|
||||||
ServerWorld overworld = server.getWorld(World.OVERWORLD);
|
ServerWorld overworld = server.getWorld(World.OVERWORLD);
|
||||||
ServerWorld backrooms = server.getWorld(Szar.BACKROOMS_KEY);
|
ServerWorld backrooms = server.getWorld(Szar.BACKROOMS_LEVEL_KEY);
|
||||||
|
|
||||||
if (owTrackerPos != null && overworld != null) {
|
if (owTrackerPos != null && overworld != null) {
|
||||||
if (overworld.getBlockEntity(owTrackerPos) instanceof TrackerBlockEntity owTracker) {
|
if (overworld.getBlockEntity(owTrackerPos) instanceof TrackerBlockEntity owTracker) {
|
||||||
@@ -307,7 +303,7 @@ public class PortalBlock extends Block {
|
|||||||
|
|
||||||
private double findSafeY(ServerWorld world, int x, int z) {
|
private double findSafeY(ServerWorld world, int x, int z) {
|
||||||
// For backrooms, search from y=8 downward only
|
// For backrooms, search from y=8 downward only
|
||||||
int startY = world.getRegistryKey() == Szar.BACKROOMS_KEY ? 8 : 100;
|
int startY = world.getRegistryKey() == Szar.BACKROOMS_LEVEL_KEY ? 8 : 100;
|
||||||
for (int y = startY; y > 1; y--) {
|
for (int y = startY; y > 1; y--) {
|
||||||
BlockPos feet = new BlockPos(x, y, z);
|
BlockPos feet = new BlockPos(x, y, z);
|
||||||
BlockPos head = feet.up();
|
BlockPos head = feet.up();
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class SmilerSpawnManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void tick(MinecraftServer server) {
|
private static void tick(MinecraftServer server) {
|
||||||
ServerWorld backrooms = server.getWorld(Szar.BACKROOMS_KEY);
|
ServerWorld backrooms = server.getWorld(Szar.BACKROOMS_LEVEL_KEY);
|
||||||
if (backrooms == null) return;
|
if (backrooms == null) return;
|
||||||
|
|
||||||
// Only spawn during blackout
|
// Only spawn during blackout
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import net.fabricmc.fabric.api.event.player.AttackEntityCallback;
|
|||||||
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
||||||
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
|
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
|
||||||
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
|
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
|
||||||
import net.fabricmc.fabric.api.loot.v2.LootTableEvents;
|
|
||||||
import net.fabricmc.fabric.api.message.v1.ServerMessageDecoratorEvent;
|
import net.fabricmc.fabric.api.message.v1.ServerMessageDecoratorEvent;
|
||||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||||
@@ -43,12 +42,7 @@ import net.minecraft.entity.effect.StatusEffect;
|
|||||||
import net.minecraft.entity.effect.StatusEffectInstance;
|
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||||
import net.minecraft.entity.passive.VillagerEntity;
|
import net.minecraft.entity.passive.VillagerEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
|
||||||
import net.minecraft.item.*;
|
import net.minecraft.item.*;
|
||||||
import net.minecraft.loot.LootPool;
|
|
||||||
import net.minecraft.loot.entry.ItemEntry;
|
|
||||||
import net.minecraft.loot.function.SetCountLootFunction;
|
|
||||||
import net.minecraft.loot.provider.number.ConstantLootNumberProvider;
|
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
import net.minecraft.network.PacketByteBuf;
|
import net.minecraft.network.PacketByteBuf;
|
||||||
import net.minecraft.registry.*;
|
import net.minecraft.registry.*;
|
||||||
@@ -71,17 +65,16 @@ import net.minecraft.util.ActionResult;
|
|||||||
import net.minecraft.util.Formatting;
|
import net.minecraft.util.Formatting;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.Rarity;
|
import net.minecraft.util.Rarity;
|
||||||
import net.minecraft.util.hit.BlockHitResult;
|
|
||||||
import net.minecraft.util.hit.HitResult;
|
|
||||||
import net.minecraft.util.math.*;
|
import net.minecraft.util.math.*;
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
import net.minecraft.util.shape.VoxelShapes;
|
import net.minecraft.util.shape.VoxelShapes;
|
||||||
import net.minecraft.village.TradeOffer;
|
import net.minecraft.village.TradeOffer;
|
||||||
import net.minecraft.village.VillagerProfession;
|
import net.minecraft.village.VillagerProfession;
|
||||||
import net.minecraft.world.Heightmap;
|
import net.minecraft.world.Heightmap;
|
||||||
import net.minecraft.world.RaycastContext;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.biome.BiomeKeys;
|
import net.minecraft.world.biome.BiomeKeys;
|
||||||
|
import net.minecraft.world.dimension.DimensionOptions;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
import net.minecraft.world.gen.GenerationStep;
|
import net.minecraft.world.gen.GenerationStep;
|
||||||
import net.minecraft.world.gen.YOffset;
|
import net.minecraft.world.gen.YOffset;
|
||||||
import net.minecraft.world.gen.feature.*;
|
import net.minecraft.world.gen.feature.*;
|
||||||
@@ -93,9 +86,10 @@ import net.minecraft.world.gen.structure.StructureType;
|
|||||||
import net.minecraft.world.poi.PointOfInterestType;
|
import net.minecraft.world.poi.PointOfInterestType;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.core.jmx.Server;
|
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@@ -106,6 +100,7 @@ public class Szar implements ModInitializer {
|
|||||||
public static final String MOD_ID = "szar";
|
public static final String MOD_ID = "szar";
|
||||||
public static final Logger LOGGER = LogManager.getLogger(MOD_ID);
|
public static final Logger LOGGER = LogManager.getLogger(MOD_ID);
|
||||||
public static MinecraftServer SERVER;
|
public static MinecraftServer SERVER;
|
||||||
|
public static final Identifier DRUNK_TYPE_PACKET = new Identifier(MOD_ID, "drunk_type");
|
||||||
public static final Identifier OPEN_DETONATOR_SCREEN = new Identifier(MOD_ID, "open_coord_screen");
|
public static final Identifier OPEN_DETONATOR_SCREEN = new Identifier(MOD_ID, "open_coord_screen");
|
||||||
public static final Identifier DETONATOR_INPUT = new Identifier(MOD_ID, "coord_input");
|
public static final Identifier DETONATOR_INPUT = new Identifier(MOD_ID, "coord_input");
|
||||||
public static final Identifier REVOLVER_SHOOT = new Identifier(MOD_ID, "revolver_shoot");
|
public static final Identifier REVOLVER_SHOOT = new Identifier(MOD_ID, "revolver_shoot");
|
||||||
@@ -174,11 +169,18 @@ public class Szar implements ModInitializer {
|
|||||||
public static final Identifier PLAY_VIDEO =
|
public static final Identifier PLAY_VIDEO =
|
||||||
new Identifier(MOD_ID, "play_video");
|
new Identifier(MOD_ID, "play_video");
|
||||||
public static final Identifier CONFIG_SYNC = new Identifier(MOD_ID, "config_sync");
|
public static final Identifier CONFIG_SYNC = new Identifier(MOD_ID, "config_sync");
|
||||||
|
public static final RegistryKey<DimensionOptions> BACKROOMS_KEY = RegistryKey.of(
|
||||||
public static final RegistryKey<World> BACKROOMS_KEY = RegistryKey.of(
|
RegistryKeys.DIMENSION,
|
||||||
|
new Identifier(MOD_ID, "backrooms")
|
||||||
|
);
|
||||||
|
public static final RegistryKey<World> BACKROOMS_LEVEL_KEY = RegistryKey.of(
|
||||||
RegistryKeys.WORLD,
|
RegistryKeys.WORLD,
|
||||||
new Identifier(MOD_ID, "backrooms")
|
new Identifier(MOD_ID, "backrooms")
|
||||||
);
|
);
|
||||||
|
public static final RegistryKey<DimensionType> BACKROOMS_DIM_TYPE = RegistryKey.of(
|
||||||
|
RegistryKeys.DIMENSION_TYPE,
|
||||||
|
new Identifier(MOD_ID, "backrooms")
|
||||||
|
);
|
||||||
public static final Block SZAR_BLOCK =
|
public static final Block SZAR_BLOCK =
|
||||||
new SzarBlock();
|
new SzarBlock();
|
||||||
public static final Block URANIUM_BLOCK =
|
public static final Block URANIUM_BLOCK =
|
||||||
@@ -946,121 +948,138 @@ public class Szar implements ModInitializer {
|
|||||||
});
|
});
|
||||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||||
dispatcher.register(
|
dispatcher.register(
|
||||||
LiteralArgumentBuilder.<ServerCommandSource>literal("ny")
|
LiteralArgumentBuilder.<ServerCommandSource>literal("szar")
|
||||||
.requires(context -> context.hasPermissionLevel(2))
|
.requires(context -> context.hasPermissionLevel(2))
|
||||||
.executes(context -> {
|
|
||||||
ServerCommandSource source = context.getSource();
|
|
||||||
ServerWorld world = source.getWorld();
|
|
||||||
|
|
||||||
// Kill all KidEntity instances
|
// /szar ny
|
||||||
int count = world.getEntitiesByType(NyanEntityType, e -> true).size();
|
.then(CommandManager.literal("ny")
|
||||||
world.getEntitiesByType(NyanEntityType, e -> true).forEach(e -> e.kill());
|
|
||||||
|
|
||||||
source.sendMessage(Text.literal("Killed " + count + " nyan cats."));
|
|
||||||
return count;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
dispatcher.register(
|
|
||||||
LiteralArgumentBuilder.<ServerCommandSource>literal("getnearestobeliskcore")
|
|
||||||
.requires(context -> context.hasPermissionLevel(2))
|
|
||||||
.executes(context -> {
|
|
||||||
ServerCommandSource source = context.getSource();
|
|
||||||
ServerWorld world = source.getWorld();
|
|
||||||
|
|
||||||
assert source.getEntity() != null;
|
|
||||||
ObeliskCoreBlockEntity nearest = findNearestObelisk(world, source.getEntity().getBlockPos(), 100);
|
|
||||||
if (nearest != null) {
|
|
||||||
boolean hasPlane = nearest.hasPlaneMob();
|
|
||||||
|
|
||||||
source.sendMessage(Text.literal(
|
|
||||||
"HasPlane: " + hasPlane
|
|
||||||
));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
dispatcher.register(
|
|
||||||
LiteralArgumentBuilder.<ServerCommandSource>literal("backroomlights")
|
|
||||||
.requires(context -> context.hasPermissionLevel(2))
|
|
||||||
.then(CommandManager.literal("get")
|
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
ServerCommandSource source = context.getSource();
|
ServerCommandSource source = context.getSource();
|
||||||
BackroomsLightManager.GlobalEvent event = BackroomsLightManager.currentEvent;
|
ServerWorld world = source.getWorld();
|
||||||
int timer = BackroomsLightManager.eventTimer;
|
int count = world.getEntitiesByType(NyanEntityType, e -> true).size();
|
||||||
|
world.getEntitiesByType(NyanEntityType, e -> true).forEach(e -> e.kill());
|
||||||
String mode = switch (event) {
|
source.sendMessage(Text.literal("Killed " + count + " nyan cats."));
|
||||||
case NONE -> "normal";
|
return count;
|
||||||
case FLICKER -> "flickering";
|
|
||||||
case BLACKOUT -> "blackout";
|
|
||||||
};
|
|
||||||
|
|
||||||
if (event == BackroomsLightManager.GlobalEvent.NONE) {
|
|
||||||
int cooldown = BackroomsLightManager.cooldownTimer;
|
|
||||||
source.sendMessage(Text.literal(
|
|
||||||
"Current mode: §anormal§r — next event check in §e"
|
|
||||||
+ cooldown + "§r ticks ("
|
|
||||||
+ (cooldown / 20) + "s)"
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
source.sendMessage(Text.literal(
|
|
||||||
"Current mode: §e" + mode + "§r — ends in §c"
|
|
||||||
+ timer + "§r ticks ("
|
|
||||||
+ (timer / 20) + "s)"
|
|
||||||
));
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.then(CommandManager.literal("set")
|
|
||||||
.then(CommandManager.literal("normal")
|
// /szar getnearestobeliskcore
|
||||||
|
.then(CommandManager.literal("getnearestobeliskcore")
|
||||||
|
.executes(context -> {
|
||||||
|
ServerCommandSource source = context.getSource();
|
||||||
|
ServerWorld world = source.getWorld();
|
||||||
|
assert source.getEntity() != null;
|
||||||
|
ObeliskCoreBlockEntity nearest = findNearestObelisk(world,
|
||||||
|
source.getEntity().getBlockPos(), 100);
|
||||||
|
if (nearest != null) {
|
||||||
|
boolean hasPlane = nearest.hasPlaneMob();
|
||||||
|
source.sendMessage(Text.literal("HasPlane: " + hasPlane));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
// /szar backroomlights get/set
|
||||||
|
.then(CommandManager.literal("backroomlights")
|
||||||
|
.then(CommandManager.literal("get")
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
ServerCommandSource source = context.getSource();
|
ServerCommandSource source = context.getSource();
|
||||||
ServerWorld backrooms = source.getServer().getWorld(Szar.BACKROOMS_KEY);
|
BackroomsLightManager.GlobalEvent event = BackroomsLightManager.currentEvent;
|
||||||
if (backrooms == null) {
|
int timer = BackroomsLightManager.eventTimer;
|
||||||
source.sendError(Text.literal("Backrooms dimension not found"));
|
String mode = switch (event) {
|
||||||
return 0;
|
case NONE -> "normal";
|
||||||
|
case FLICKER -> "flickering";
|
||||||
|
case BLACKOUT -> "blackout";
|
||||||
|
};
|
||||||
|
if (event == BackroomsLightManager.GlobalEvent.NONE) {
|
||||||
|
int cooldown = BackroomsLightManager.cooldownTimer;
|
||||||
|
source.sendMessage(Text.literal(
|
||||||
|
"Current mode: §anormal§r — next event check in §e"
|
||||||
|
+ cooldown + "§r ticks (" + (cooldown / 20) + "s)"));
|
||||||
|
} else {
|
||||||
|
source.sendMessage(Text.literal(
|
||||||
|
"Current mode: §e" + mode + "§r — ends in §c"
|
||||||
|
+ timer + "§r ticks (" + (timer / 20) + "s)"));
|
||||||
}
|
}
|
||||||
// End current event cleanly
|
|
||||||
BackroomsLightManager.currentEvent = BackroomsLightManager.GlobalEvent.NONE;
|
|
||||||
BackroomsLightManager.eventTimer = 0;
|
|
||||||
BackroomsLightManager.cooldownTimer = 3600;
|
|
||||||
// Restore all lights
|
|
||||||
BackroomsLightManager.forceRestoreAllLights(backrooms);
|
|
||||||
source.sendMessage(Text.literal("§aBackrooms lights set to normal"));
|
|
||||||
return 1;
|
return 1;
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.then(CommandManager.literal("flickering")
|
.then(CommandManager.literal("set")
|
||||||
.executes(context -> {
|
.then(CommandManager.literal("normal")
|
||||||
ServerCommandSource source = context.getSource();
|
.executes(context -> {
|
||||||
ServerWorld backrooms = source.getServer().getWorld(Szar.BACKROOMS_KEY);
|
ServerCommandSource source = context.getSource();
|
||||||
if (backrooms == null) {
|
ServerWorld backrooms = source.getServer().getWorld(Szar.BACKROOMS_LEVEL_KEY);
|
||||||
source.sendError(Text.literal("Backrooms dimension not found"));
|
if (backrooms == null) {
|
||||||
return 0;
|
source.sendError(Text.literal("Backrooms dimension not found"));
|
||||||
}
|
return 0;
|
||||||
BackroomsLightManager.currentEvent = BackroomsLightManager.GlobalEvent.FLICKER;
|
}
|
||||||
BackroomsLightManager.eventTimer = 3600; // 3 minutes default
|
BackroomsLightManager.currentEvent = BackroomsLightManager.GlobalEvent.NONE;
|
||||||
BackroomsLightManager.cooldownTimer = 3600;
|
BackroomsLightManager.eventTimer = 0;
|
||||||
source.sendMessage(Text.literal("§eBackrooms lights set to flickering"));
|
BackroomsLightManager.cooldownTimer = 3600;
|
||||||
return 1;
|
BackroomsLightManager.forceRestoreAllLights(backrooms);
|
||||||
})
|
source.sendMessage(Text.literal("§aBackrooms lights set to normal"));
|
||||||
|
return 1;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.then(CommandManager.literal("flickering")
|
||||||
|
.executes(context -> {
|
||||||
|
ServerCommandSource source = context.getSource();
|
||||||
|
ServerWorld backrooms = source.getServer().getWorld(Szar.BACKROOMS_LEVEL_KEY);
|
||||||
|
if (backrooms == null) {
|
||||||
|
source.sendError(Text.literal("Backrooms dimension not found"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
BackroomsLightManager.currentEvent = BackroomsLightManager.GlobalEvent.FLICKER;
|
||||||
|
BackroomsLightManager.eventTimer = 3600;
|
||||||
|
BackroomsLightManager.cooldownTimer = 3600;
|
||||||
|
source.sendMessage(Text.literal("§eBackrooms lights set to flickering"));
|
||||||
|
return 1;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.then(CommandManager.literal("blackout")
|
||||||
|
.executes(context -> {
|
||||||
|
ServerCommandSource source = context.getSource();
|
||||||
|
ServerWorld backrooms = source.getServer().getWorld(Szar.BACKROOMS_LEVEL_KEY);
|
||||||
|
if (backrooms == null) {
|
||||||
|
source.sendError(Text.literal("Backrooms dimension not found"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
BackroomsLightManager.currentEvent = BackroomsLightManager.GlobalEvent.BLACKOUT;
|
||||||
|
BackroomsLightManager.eventTimer = 3600;
|
||||||
|
BackroomsLightManager.cooldownTimer = 3600;
|
||||||
|
BackroomsLightManager.forceBlackout(backrooms);
|
||||||
|
source.sendMessage(Text.literal("§4Backrooms lights set to blackout"));
|
||||||
|
return 1;
|
||||||
|
})
|
||||||
|
)
|
||||||
)
|
)
|
||||||
.then(CommandManager.literal("blackout")
|
)
|
||||||
.executes(context -> {
|
|
||||||
ServerCommandSource source = context.getSource();
|
// /szar drunk <targets> <type>
|
||||||
ServerWorld backrooms = source.getServer().getWorld(Szar.BACKROOMS_KEY);
|
.then(CommandManager.literal("drunk")
|
||||||
if (backrooms == null) {
|
.then(CommandManager.argument("targets",
|
||||||
source.sendError(Text.literal("Backrooms dimension not found"));
|
net.minecraft.command.argument.EntityArgumentType.players())
|
||||||
return 0;
|
.then(CommandManager.literal("aggressive")
|
||||||
}
|
.executes(ctx -> applyDrunk(ctx,
|
||||||
BackroomsLightManager.currentEvent = BackroomsLightManager.GlobalEvent.BLACKOUT;
|
net.minecraft.command.argument.EntityArgumentType.getPlayers(ctx, "targets"),
|
||||||
BackroomsLightManager.eventTimer = 3600;
|
DrunkEffect.DrunkType.AGGRESSIVE)))
|
||||||
BackroomsLightManager.cooldownTimer = 3600;
|
.then(CommandManager.literal("stumbling")
|
||||||
BackroomsLightManager.forceBlackout(backrooms);
|
.executes(ctx -> applyDrunk(ctx,
|
||||||
source.sendMessage(Text.literal("§4Backrooms lights set to blackout"));
|
net.minecraft.command.argument.EntityArgumentType.getPlayers(ctx, "targets"),
|
||||||
return 1;
|
DrunkEffect.DrunkType.STUMBLING)))
|
||||||
})
|
.then(CommandManager.literal("sleepy")
|
||||||
|
.executes(ctx -> applyDrunk(ctx,
|
||||||
|
net.minecraft.command.argument.EntityArgumentType.getPlayers(ctx, "targets"),
|
||||||
|
DrunkEffect.DrunkType.SLEEPY)))
|
||||||
|
.then(CommandManager.literal("generous")
|
||||||
|
.executes(ctx -> applyDrunk(ctx,
|
||||||
|
net.minecraft.command.argument.EntityArgumentType.getPlayers(ctx, "targets"),
|
||||||
|
DrunkEffect.DrunkType.GENEROUS)))
|
||||||
|
.then(CommandManager.literal("paranoid")
|
||||||
|
.executes(ctx -> applyDrunk(ctx,
|
||||||
|
net.minecraft.command.argument.EntityArgumentType.getPlayers(ctx, "targets"),
|
||||||
|
DrunkEffect.DrunkType.PARANOID)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -1186,7 +1205,7 @@ public class Szar implements ModInitializer {
|
|||||||
SmilerSpawnManager.register();
|
SmilerSpawnManager.register();
|
||||||
// 🔄 Dimension change
|
// 🔄 Dimension change
|
||||||
ServerEntityWorldChangeEvents.AFTER_PLAYER_CHANGE_WORLD.register((player, origin, destination) -> {
|
ServerEntityWorldChangeEvents.AFTER_PLAYER_CHANGE_WORLD.register((player, origin, destination) -> {
|
||||||
if (origin.getRegistryKey() == Szar.BACKROOMS_KEY) {
|
if (origin.getRegistryKey() == Szar.BACKROOMS_LEVEL_KEY) {
|
||||||
restoreIfNeeded(player);
|
restoreIfNeeded(player);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1202,7 +1221,7 @@ public class Szar implements ModInitializer {
|
|||||||
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
|
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
|
||||||
ServerPlayerEntity player = handler.getPlayer();
|
ServerPlayerEntity player = handler.getPlayer();
|
||||||
|
|
||||||
if (player.getWorld().getRegistryKey() != Szar.BACKROOMS_KEY) {
|
if (player.getWorld().getRegistryKey() != Szar.BACKROOMS_LEVEL_KEY) {
|
||||||
restoreIfNeeded(player);
|
restoreIfNeeded(player);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -2267,5 +2286,26 @@ public class Szar implements ModInitializer {
|
|||||||
tag.remove("OwnerTrackerY");
|
tag.remove("OwnerTrackerY");
|
||||||
tag.remove("OwnerTrackerZ");
|
tag.remove("OwnerTrackerZ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int applyDrunk(com.mojang.brigadier.context.CommandContext<ServerCommandSource> ctx,
|
||||||
|
java.util.Collection<ServerPlayerEntity> players,
|
||||||
|
DrunkEffect.DrunkType type) {
|
||||||
|
for (ServerPlayerEntity player : players) {
|
||||||
|
// Pre-assign the type before applying effect so tick() doesn't randomize it
|
||||||
|
DrunkEffect.preAssignType(player.getUuid(), type);
|
||||||
|
|
||||||
|
player.addStatusEffect(new net.minecraft.entity.effect.StatusEffectInstance(
|
||||||
|
Szar.DRUNK_EFFECT, 2400, 0, false, true, true));
|
||||||
|
|
||||||
|
// Sync type to client immediately
|
||||||
|
String typeName = type.name().charAt(0) + type.name().substring(1).toLowerCase();
|
||||||
|
net.minecraft.network.PacketByteBuf buf =
|
||||||
|
net.fabricmc.fabric.api.networking.v1.PacketByteBufs.create();
|
||||||
|
buf.writeString(typeName);
|
||||||
|
net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking.send(
|
||||||
|
player, Szar.DRUNK_TYPE_PACKET, buf);
|
||||||
|
}
|
||||||
|
return players.size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package dev.tggamesyt.szar.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.storage.LevelSummary;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
@Mixin(value = LevelSummary.class, priority = 1001)
|
||||||
|
public class LevelSummaryMixin {
|
||||||
|
@Inject(method = "isExperimental", at = @At(value = "RETURN"), cancellable = true)
|
||||||
|
public void isExperimental(CallbackInfoReturnable<Boolean> cir) {
|
||||||
|
cir.setReturnValue(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
"mixins": [
|
"mixins": [
|
||||||
"CraftingScreenHandlerMixin",
|
"CraftingScreenHandlerMixin",
|
||||||
"CraftingScreenHandlerMixin2",
|
"CraftingScreenHandlerMixin2",
|
||||||
|
"LevelSummaryMixin",
|
||||||
"LivingEntityFallDamageMixin",
|
"LivingEntityFallDamageMixin",
|
||||||
"NoClipMixin",
|
"NoClipMixin",
|
||||||
"PlaneBlockInteractionMixin",
|
"PlaneBlockInteractionMixin",
|
||||||
|
|||||||
Reference in New Issue
Block a user