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
|
||||
loader_version=0.18.3
|
||||
# Mod Properties
|
||||
mod_version=26.3.20
|
||||
mod_version=26.3.21
|
||||
maven_group=dev.tggamesyt
|
||||
archives_base_name=szar
|
||||
# Dependencies
|
||||
|
||||
@@ -21,8 +21,11 @@ import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.lit
|
||||
public class PanoramaClientCommand {
|
||||
|
||||
static void register(CommandDispatcher<FabricClientCommandSource> dispatcher) {
|
||||
dispatcher.register(literal("takepanorama")
|
||||
.executes(PanoramaClientCommand::execute));
|
||||
dispatcher.register(
|
||||
literal("szar")
|
||||
.then(literal("takepanorama")
|
||||
.executes(PanoramaClientCommand::execute))
|
||||
);
|
||||
}
|
||||
|
||||
private static int execute(CommandContext<FabricClientCommandSource> context) {
|
||||
|
||||
@@ -93,6 +93,10 @@ public class SzarClient implements ClientModInitializer {
|
||||
);
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
ClientPlayNetworking.registerGlobalReceiver(Szar.DRUNK_TYPE_PACKET, (client, handler, buf, responseSender) -> {
|
||||
String typeName = buf.readString();
|
||||
client.execute(() -> DrunkEffect.setDisplayType(typeName));
|
||||
});
|
||||
SmilerEffectRenderer.register();
|
||||
EntityRendererRegistry.register(Szar.SMILER_ENTITY_TYPE, SmilerRenderer::new);
|
||||
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",
|
||||
"client": [
|
||||
"BipedEntityModelMixin",
|
||||
"CreateWorldScreenMixin",
|
||||
"EntityRenderMixin",
|
||||
"GameRendererMixin",
|
||||
"HeldItemRendererMixin",
|
||||
"IntegratedServerLoaderMixin",
|
||||
"ItemRendererMixin",
|
||||
"LogoDrawerMixin",
|
||||
"MouseFlipMixin",
|
||||
|
||||
@@ -38,7 +38,7 @@ public class BackroomsBarrelManager {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
List<ServerPlayerEntity> players = backrooms.getPlayers();
|
||||
|
||||
@@ -31,7 +31,7 @@ public class BackroomsLightManager {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
globalFlickerTimer++;
|
||||
|
||||
@@ -4,55 +4,209 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.effect.StatusEffect;
|
||||
import net.minecraft.entity.effect.StatusEffectCategory;
|
||||
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.ProjectileUtil;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.packet.s2c.play.EntityAnimationS2CPacket;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
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.HitResult;
|
||||
import net.minecraft.world.RaycastContext;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
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() {
|
||||
super(StatusEffectCategory.HARMFUL, 0xFF9900);
|
||||
}
|
||||
|
||||
static void tick(MinecraftServer server) {
|
||||
for (var world : server.getWorlds()) {
|
||||
if (world.getTime() % 20 != 0) continue;
|
||||
|
||||
for (ServerPlayerEntity player : world.getPlayers()) {
|
||||
if (!player.hasStatusEffect(Szar.DRUNK_EFFECT)) continue;
|
||||
if (world.random.nextInt(5) >= 2) continue; // 2 in 5 chance
|
||||
if (!player.hasStatusEffect(Szar.DRUNK_EFFECT)) {
|
||||
// Clean up when effect ends
|
||||
playerTypes.remove(player.getUuid());
|
||||
sleepyTimer.remove(player.getUuid());
|
||||
continue;
|
||||
}
|
||||
|
||||
double reach = 4.5;
|
||||
net.minecraft.util.math.Vec3d eyePos = player.getEyePos();
|
||||
net.minecraft.util.math.Vec3d lookVec = player.getRotationVector();
|
||||
net.minecraft.util.math.Vec3d endPos = eyePos.add(lookVec.multiply(reach));
|
||||
// Assign type if not yet assigned
|
||||
DrunkType type = playerTypes.computeIfAbsent(player.getUuid(), k -> {
|
||||
DrunkType[] values = DrunkType.values();
|
||||
DrunkType assigned = values[world.random.nextInt(values.length)];
|
||||
|
||||
EntityHitResult entityHit = net.minecraft.entity.projectile.ProjectileUtil
|
||||
.getEntityCollision(
|
||||
world,
|
||||
player,
|
||||
eyePos,
|
||||
endPos,
|
||||
player.getBoundingBox().stretch(lookVec.multiply(reach)).expand(1.0),
|
||||
String typeName = assigned.name().charAt(0)
|
||||
+ assigned.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 assigned;
|
||||
});
|
||||
|
||||
switch (type) {
|
||||
case AGGRESSIVE -> tickAggressive(world, player);
|
||||
case STUMBLING -> tickStumbling(world, player);
|
||||
case SLEEPY -> tickSleepy(world, player);
|
||||
case GENEROUS -> tickGenerous(world, player);
|
||||
case PARANOID -> tickParanoid(world, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- 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 (entityHit == null) continue;
|
||||
if (!(entityHit.getEntity() instanceof LivingEntity target)) continue;
|
||||
if (hit == null) return;
|
||||
if (!(hit.getEntity() instanceof LivingEntity target)) return;
|
||||
|
||||
player.attack(target);
|
||||
player.swingHand(net.minecraft.util.Hand.MAIN_HAND);
|
||||
player.swingHand(Hand.MAIN_HAND);
|
||||
player.networkHandler.sendPacket(new EntityAnimationS2CPacket(player, 0));
|
||||
}
|
||||
|
||||
EntityAnimationS2CPacket swingPacket =
|
||||
new EntityAnimationS2CPacket(
|
||||
player, 0); // 0 = swing main hand
|
||||
player.networkHandler.sendPacket(swingPacket);
|
||||
// --- 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.entity.Entity;
|
||||
import net.minecraft.entity.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtList;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.util.shape.VoxelShapes;
|
||||
@@ -58,13 +54,13 @@ public class PortalBlock extends Block {
|
||||
// Full player handling — inventory save, tracker registration, etc.
|
||||
if (world.getRegistryKey() == World.OVERWORLD) {
|
||||
teleportToNether(player, tracker, server, pos);
|
||||
} else if (world.getRegistryKey() == Szar.BACKROOMS_KEY) {
|
||||
} else if (world.getRegistryKey() == Szar.BACKROOMS_LEVEL_KEY) {
|
||||
teleportToOverworld(player, tracker, server);
|
||||
}
|
||||
} else {
|
||||
// Non-player entity — teleport only, no inventory or tracker registration
|
||||
if (world.getRegistryKey() == World.OVERWORLD) {
|
||||
ServerWorld backrooms = server.getWorld(Szar.BACKROOMS_KEY);
|
||||
ServerWorld backrooms = server.getWorld(Szar.BACKROOMS_LEVEL_KEY);
|
||||
if (backrooms == null) return;
|
||||
|
||||
// Save overworld entry coords for this entity
|
||||
@@ -75,7 +71,7 @@ public class PortalBlock extends Block {
|
||||
entity.teleport(backrooms, entity.getX(), safeY, entity.getZ(),
|
||||
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);
|
||||
if (overworld == null) return;
|
||||
|
||||
@@ -134,7 +130,7 @@ public class PortalBlock extends Block {
|
||||
tracker.addPlayer(player.getUuid());
|
||||
|
||||
// Teleport
|
||||
ServerWorld nether = server.getWorld(Szar.BACKROOMS_KEY);
|
||||
ServerWorld nether = server.getWorld(Szar.BACKROOMS_LEVEL_KEY);
|
||||
if (nether == null) return;
|
||||
|
||||
double netherX = player.getX();
|
||||
@@ -179,7 +175,7 @@ public class PortalBlock extends Block {
|
||||
netherTracker.removePlayer(player.getUuid());
|
||||
|
||||
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 (overworld.getBlockEntity(owTrackerPos) instanceof TrackerBlockEntity owTracker) {
|
||||
@@ -307,7 +303,7 @@ public class PortalBlock extends Block {
|
||||
|
||||
private double findSafeY(ServerWorld world, int x, int z) {
|
||||
// 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--) {
|
||||
BlockPos feet = new BlockPos(x, y, z);
|
||||
BlockPos head = feet.up();
|
||||
|
||||
@@ -26,7 +26,7 @@ public class SmilerSpawnManager {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// 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.item.v1.FabricItemSettings;
|
||||
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.networking.v1.PacketByteBufs;
|
||||
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.passive.VillagerEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
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.network.PacketByteBuf;
|
||||
import net.minecraft.registry.*;
|
||||
@@ -71,17 +65,16 @@ import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.minecraft.util.Identifier;
|
||||
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.shape.VoxelShape;
|
||||
import net.minecraft.util.shape.VoxelShapes;
|
||||
import net.minecraft.village.TradeOffer;
|
||||
import net.minecraft.village.VillagerProfession;
|
||||
import net.minecraft.world.Heightmap;
|
||||
import net.minecraft.world.RaycastContext;
|
||||
import net.minecraft.world.World;
|
||||
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.YOffset;
|
||||
import net.minecraft.world.gen.feature.*;
|
||||
@@ -93,9 +86,10 @@ import net.minecraft.world.gen.structure.StructureType;
|
||||
import net.minecraft.world.poi.PointOfInterestType;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.core.jmx.Server;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -106,6 +100,7 @@ public class Szar implements ModInitializer {
|
||||
public static final String MOD_ID = "szar";
|
||||
public static final Logger LOGGER = LogManager.getLogger(MOD_ID);
|
||||
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 DETONATOR_INPUT = new Identifier(MOD_ID, "coord_input");
|
||||
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 =
|
||||
new Identifier(MOD_ID, "play_video");
|
||||
public static final Identifier CONFIG_SYNC = new Identifier(MOD_ID, "config_sync");
|
||||
|
||||
public static final RegistryKey<World> BACKROOMS_KEY = RegistryKey.of(
|
||||
public static final RegistryKey<DimensionOptions> BACKROOMS_KEY = RegistryKey.of(
|
||||
RegistryKeys.DIMENSION,
|
||||
new Identifier(MOD_ID, "backrooms")
|
||||
);
|
||||
public static final RegistryKey<World> BACKROOMS_LEVEL_KEY = RegistryKey.of(
|
||||
RegistryKeys.WORLD,
|
||||
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 =
|
||||
new SzarBlock();
|
||||
public static final Block URANIUM_BLOCK =
|
||||
@@ -946,68 +948,59 @@ public class Szar implements ModInitializer {
|
||||
});
|
||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||
dispatcher.register(
|
||||
LiteralArgumentBuilder.<ServerCommandSource>literal("ny")
|
||||
LiteralArgumentBuilder.<ServerCommandSource>literal("szar")
|
||||
.requires(context -> context.hasPermissionLevel(2))
|
||||
|
||||
// /szar ny
|
||||
.then(CommandManager.literal("ny")
|
||||
.executes(context -> {
|
||||
ServerCommandSource source = context.getSource();
|
||||
ServerWorld world = source.getWorld();
|
||||
|
||||
// Kill all KidEntity instances
|
||||
int count = world.getEntitiesByType(NyanEntityType, e -> true).size();
|
||||
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))
|
||||
)
|
||||
|
||||
// /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);
|
||||
ObeliskCoreBlockEntity nearest = findNearestObelisk(world,
|
||||
source.getEntity().getBlockPos(), 100);
|
||||
if (nearest != null) {
|
||||
boolean hasPlane = nearest.hasPlaneMob();
|
||||
|
||||
source.sendMessage(Text.literal(
|
||||
"HasPlane: " + hasPlane
|
||||
));
|
||||
source.sendMessage(Text.literal("HasPlane: " + hasPlane));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
})
|
||||
);
|
||||
dispatcher.register(
|
||||
LiteralArgumentBuilder.<ServerCommandSource>literal("backroomlights")
|
||||
.requires(context -> context.hasPermissionLevel(2))
|
||||
)
|
||||
|
||||
// /szar backroomlights get/set
|
||||
.then(CommandManager.literal("backroomlights")
|
||||
.then(CommandManager.literal("get")
|
||||
.executes(context -> {
|
||||
ServerCommandSource source = context.getSource();
|
||||
BackroomsLightManager.GlobalEvent event = BackroomsLightManager.currentEvent;
|
||||
int timer = BackroomsLightManager.eventTimer;
|
||||
|
||||
String mode = switch (event) {
|
||||
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)"
|
||||
));
|
||||
+ 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)"
|
||||
));
|
||||
+ timer + "§r ticks (" + (timer / 20) + "s)"));
|
||||
}
|
||||
return 1;
|
||||
})
|
||||
@@ -1016,16 +1009,14 @@ public class Szar implements ModInitializer {
|
||||
.then(CommandManager.literal("normal")
|
||||
.executes(context -> {
|
||||
ServerCommandSource source = context.getSource();
|
||||
ServerWorld backrooms = source.getServer().getWorld(Szar.BACKROOMS_KEY);
|
||||
ServerWorld backrooms = source.getServer().getWorld(Szar.BACKROOMS_LEVEL_KEY);
|
||||
if (backrooms == null) {
|
||||
source.sendError(Text.literal("Backrooms dimension not found"));
|
||||
return 0;
|
||||
}
|
||||
// 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;
|
||||
@@ -1034,13 +1025,13 @@ public class Szar implements ModInitializer {
|
||||
.then(CommandManager.literal("flickering")
|
||||
.executes(context -> {
|
||||
ServerCommandSource source = context.getSource();
|
||||
ServerWorld backrooms = source.getServer().getWorld(Szar.BACKROOMS_KEY);
|
||||
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; // 3 minutes default
|
||||
BackroomsLightManager.eventTimer = 3600;
|
||||
BackroomsLightManager.cooldownTimer = 3600;
|
||||
source.sendMessage(Text.literal("§eBackrooms lights set to flickering"));
|
||||
return 1;
|
||||
@@ -1049,7 +1040,7 @@ public class Szar implements ModInitializer {
|
||||
.then(CommandManager.literal("blackout")
|
||||
.executes(context -> {
|
||||
ServerCommandSource source = context.getSource();
|
||||
ServerWorld backrooms = source.getServer().getWorld(Szar.BACKROOMS_KEY);
|
||||
ServerWorld backrooms = source.getServer().getWorld(Szar.BACKROOMS_LEVEL_KEY);
|
||||
if (backrooms == null) {
|
||||
source.sendError(Text.literal("Backrooms dimension not found"));
|
||||
return 0;
|
||||
@@ -1063,6 +1054,34 @@ public class Szar implements ModInitializer {
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
// /szar drunk <targets> <type>
|
||||
.then(CommandManager.literal("drunk")
|
||||
.then(CommandManager.argument("targets",
|
||||
net.minecraft.command.argument.EntityArgumentType.players())
|
||||
.then(CommandManager.literal("aggressive")
|
||||
.executes(ctx -> applyDrunk(ctx,
|
||||
net.minecraft.command.argument.EntityArgumentType.getPlayers(ctx, "targets"),
|
||||
DrunkEffect.DrunkType.AGGRESSIVE)))
|
||||
.then(CommandManager.literal("stumbling")
|
||||
.executes(ctx -> applyDrunk(ctx,
|
||||
net.minecraft.command.argument.EntityArgumentType.getPlayers(ctx, "targets"),
|
||||
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)))
|
||||
)
|
||||
)
|
||||
);
|
||||
});
|
||||
Registry.register(
|
||||
@@ -1186,7 +1205,7 @@ public class Szar implements ModInitializer {
|
||||
SmilerSpawnManager.register();
|
||||
// 🔄 Dimension change
|
||||
ServerEntityWorldChangeEvents.AFTER_PLAYER_CHANGE_WORLD.register((player, origin, destination) -> {
|
||||
if (origin.getRegistryKey() == Szar.BACKROOMS_KEY) {
|
||||
if (origin.getRegistryKey() == Szar.BACKROOMS_LEVEL_KEY) {
|
||||
restoreIfNeeded(player);
|
||||
}
|
||||
});
|
||||
@@ -1202,7 +1221,7 @@ public class Szar implements ModInitializer {
|
||||
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
|
||||
ServerPlayerEntity player = handler.getPlayer();
|
||||
|
||||
if (player.getWorld().getRegistryKey() != Szar.BACKROOMS_KEY) {
|
||||
if (player.getWorld().getRegistryKey() != Szar.BACKROOMS_LEVEL_KEY) {
|
||||
restoreIfNeeded(player);
|
||||
}
|
||||
});
|
||||
@@ -2267,5 +2286,26 @@ public class Szar implements ModInitializer {
|
||||
tag.remove("OwnerTrackerY");
|
||||
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": [
|
||||
"CraftingScreenHandlerMixin",
|
||||
"CraftingScreenHandlerMixin2",
|
||||
"LevelSummaryMixin",
|
||||
"LivingEntityFallDamageMixin",
|
||||
"NoClipMixin",
|
||||
"PlaneBlockInteractionMixin",
|
||||
|
||||
Reference in New Issue
Block a user