Compare commits

..

3 Commits

13 changed files with 385 additions and 51 deletions

View File

@ -20,6 +20,16 @@ public class ModConfig {
public static final Option<Boolean> ENABLE_CLOUDS = make("Enable Clouds", true, "Enables the rendering of clouds"); public static final Option<Boolean> ENABLE_CLOUDS = make("Enable Clouds", true, "Enables the rendering of clouds");
public static final Option<Boolean> DISABLE_ID_TAGS = make("Disable ID Tags", true, public static final Option<Boolean> DISABLE_ID_TAGS = make("Disable ID Tags", true,
"Disables id tags showing above entities in F3 mode"); "Disables id tags showing above entities in F3 mode");
public static final Option<Boolean> FENCE_SLIM_HITBOX = make("Slim Hitbox for Fences", true,
"Uses slim hitbox for fences on the X and Z axies (the height of the fence is not changed)");
public static final Option<Boolean> REMOVE_NIGHTMARES = make("Remove Nightmares", false,
"Removes nightmares completely");
public static final Option<Boolean> DISABLE_BEDS = make("Disable Beds", false,
"Disables bed mechanics such as setting spawn points and skipping the night, does NOT delete already placed blocks nor does it disable the crafting or placing of beds as decorative blocks");
public static final Option<Integer> BOAT_BREAKING_LOGIC = make("Boat Breaking Logic", 2,
"0 - Vanilla behavior\n1 - Boats will never break regardless of their speed\n2 - Boats will only break when crashing with almost max speed");
public static final Option<Boolean> STACK_DROP = make("Drop Held Stack", true,
"Allows the player to drop the entire stack they're holding using Shift + Q (or whatever drop key they have set)");
public static final Option<Boolean> FIX_BOW_MODEL = make("Fix bow model", true, public static final Option<Boolean> FIX_BOW_MODEL = make("Fix bow model", true,
"Makes the box model held by players and skeletons bigger and facing forward"); "Makes the box model held by players and skeletons bigger and facing forward");
@ -39,6 +49,8 @@ public class ModConfig {
"Fixes saddles not dropping when killing saddled pigs"); "Fixes saddles not dropping when killing saddled pigs");
public static final Option<Boolean> FIX_FURNACE_LAVA_BUCKET = make("Fix furnace lava bucket", true, public static final Option<Boolean> FIX_FURNACE_LAVA_BUCKET = make("Fix furnace lava bucket", true,
"Fixes furnaces consuming the bucket when using lava buckets as fuel"); "Fixes furnaces consuming the bucket when using lava buckets as fuel");
public static final Option<Boolean> FIX_BOOKSHELVES_DROP = make("Fix Bookshelves Drops", true,
"Drops 3 books when breaking a bookshelf");
private static ModConfig instance = new ModConfig(); private static ModConfig instance = new ModConfig();
public static final ModConfig instance() { public static final ModConfig instance() {

View File

@ -6,6 +6,8 @@ import java.time.Duration;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.Player; import net.minecraft.entity.player.Player;
import net.minecraft.item.ItemInstance;
import net.minecraft.item.ItemType;
import net.minecraft.stat.Stats; import net.minecraft.stat.Stats;
public class WyHelper { public class WyHelper {
@ -54,6 +56,23 @@ public class WyHelper {
public static void cheatCommand(Player player) { public static void cheatCommand(Player player) {
player.dropItem(new ItemInstance(ItemType.boat, 1));
// int x = MathsHelper.floor(player.x);
// int y = MathsHelper.floor(player.boundingBox.minY);
// int z = MathsHelper.floor(player.z);
// int lightLevel = player.level.getLightLevel(x, y, z);
// System.out.println(lightLevel);
// player.dropItem(new ItemInstance(ItemType.swordDiamond, 1));
// player.dropItem(new ItemInstance(Tile.TORCH, 64));
// player.dropItem(new ItemInstance(Tile.BED, 64));
// player.dropItem(new ItemInstance(Tile.FENCE, 64));
// player.dropItem(new ItemInstance(Tile.STONE_PRESSURE_PLATE, 64));
// player.dropItem(new ItemInstance(Tile.BOOKSHELF, 64));
// player.dropItem(new ItemInstance(Tile.SNOW)); // player.dropItem(new ItemInstance(Tile.SNOW));
// Random rand = new Random(); // Random rand = new Random();
// player.level.playSound(player, "random.break", 1, (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); // player.level.playSound(player, "random.break", 1, (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F);
@ -73,14 +92,16 @@ public class WyHelper {
// player.dropItem(new ItemInstance(Tile.RAIL, 64), false); // player.dropItem(new ItemInstance(Tile.RAIL, 64), false);
// player.dropItem(new ItemInstance(Tile.GOLDEN_RAIL, 64), false); // player.dropItem(new ItemInstance(Tile.GOLDEN_RAIL, 64), false);
// Zombie enemy = new Zombie(player.level); // player.dropItem(new ItemInstance(ItemType.saddle, 1));
// enemy.setPositionAndAngles(player.x + 2, player.y, player.z, 0.0f, 0.0f); //
// player.level.spawnEntity(enemy); // Pig animal = new Pig(player.level);
// animal.setPositionAndAngles(player.x + 2, player.y, player.z, 0.0f, 0.0f);
// player.level.spawnEntity(animal);
// player.level.setLevelTime(0); player.level.setLevelTime(0);
// player.level.getProperties().setRaining(false); player.level.getProperties().setRaining(false);
// player.level.getProperties().setRainTime(0); player.level.getProperties().setRainTime(0);
// player.level.getProperties().setThundering(false); player.level.getProperties().setThundering(false);
// player.level.getProperties().setThunderTime(0); player.level.getProperties().setThunderTime(0);
} }
} }

View File

@ -0,0 +1,23 @@
package xyz.pixelatedw.finalbeta.mixin;
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;
import net.minecraft.entity.player.Player;
import net.minecraft.level.Level;
import net.minecraft.tile.BedTile;
import xyz.pixelatedw.finalbeta.ModConfig;
@Mixin(BedTile.class)
public class BedTileMixin {
@Inject(method = "activate", at = @At("HEAD"), cancellable = true)
public void activate(Level level, int x, int y, int z, Player player, CallbackInfoReturnable<Boolean> cir) {
if (ModConfig.DISABLE_BEDS.get()) {
cir.setReturnValue(false);
}
}
}

View File

@ -0,0 +1,49 @@
package xyz.pixelatedw.finalbeta.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.At.Shift;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.entity.Boat;
import xyz.pixelatedw.finalbeta.ModConfig;
@Mixin(Boat.class)
public class BoatMixin {
@Inject(method = "tick", at = @At(value = "INVOKE", target = "Ljava/lang/Math;sqrt(D)D", shift = Shift.AFTER))
public void boatVelocityCheck(CallbackInfo ci) {
Boat boat = ((Boat) (Object) this);
/*
* This randomly named field_1624 is actually the horizontal collision
* check, which we're setting to false before the vanilla check happens
* if the boat is set to survive the impact from our checks.
*
* Do note that they way the boat collision check happens is that the
* boat gets slowed down first, and then the velocity check is
* performed, by default a velocity check is 0.15, we're raising that
* limit to 0.22.
*/
if (this.isCollidingHorizontally(boat) && this.canSurvive(boat)) {
((Boat) (Object) this).field_1624 = false;
}
}
private boolean canSurvive(Boat boat) {
double velocity = Math.sqrt(boat.velocityX * boat.velocityX + boat.velocityZ * boat.velocityZ);
boolean survives = false;
if (ModConfig.BOAT_BREAKING_LOGIC.get() == 1) {
survives = true;
} else if (ModConfig.BOAT_BREAKING_LOGIC.get() == 2 && velocity < 0.22) {
survives = true;
}
return survives;
}
private boolean isCollidingHorizontally(Boat boat) {
return ((Boat) (Object) this).field_1624;
}
}

View File

@ -0,0 +1,38 @@
package xyz.pixelatedw.finalbeta.mixin;
import java.util.Random;
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;
import net.minecraft.item.ItemType;
import net.minecraft.tile.BookshelfTile;
import net.minecraft.tile.Tile;
import net.minecraft.tile.material.Material;
import xyz.pixelatedw.finalbeta.ModConfig;
@Mixin(BookshelfTile.class)
public class BookshelfTileMixin extends Tile {
public BookshelfTileMixin(int i, Material j) {
super(i, j);
}
@Inject(method = "getDropCount", at = @At("HEAD"), cancellable = true)
public void getDropCount(Random random, CallbackInfoReturnable<Integer> cir) {
if (ModConfig.FIX_BOOKSHELVES_DROP.get()) {
cir.setReturnValue(3);
}
}
@Override
public int getDropId(int i, Random random) {
if (ModConfig.FIX_BOOKSHELVES_DROP.get()) {
return ItemType.book.id;
}
return super.getDropId(i, random);
}
}

View File

@ -8,10 +8,12 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.client.Minecraft;
import net.minecraft.container.ChestContainer; import net.minecraft.container.ChestContainer;
import net.minecraft.entity.player.ClientPlayer; import net.minecraft.entity.player.ClientPlayer;
import net.minecraft.entity.player.Player; import net.minecraft.entity.player.Player;
import net.minecraft.inventory.Inventory; import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemInstance;
import xyz.pixelatedw.finalbeta.ModConfig; import xyz.pixelatedw.finalbeta.ModConfig;
import xyz.pixelatedw.finalbeta.WyHelper; import xyz.pixelatedw.finalbeta.WyHelper;
@ -22,15 +24,31 @@ public class ClientPlayerMixin {
@Inject(method = "method_136", at = @At("TAIL")) @Inject(method = "method_136", at = @At("TAIL"))
public void onKeyPressed(int key, boolean state, CallbackInfo ci) { public void onKeyPressed(int key, boolean state, CallbackInfo ci) {
if (WyHelper.isDebug() && key == Keyboard.KEY_Z && state) { Minecraft mc = WyHelper.getInstance();
Player player = (Player) (Object) this; Player player = (Player) (Object) this;
if (player.vehicle != null && key == Keyboard.KEY_LSHIFT) {
player.startRiding(null);
return;
}
if (ModConfig.STACK_DROP.get() && key == mc.options.dropKey.key && Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) {
ItemInstance heldItem = player.inventory.getHeldItem();
if (heldItem != null && heldItem.count > 0) {
player.dropItem(player.inventory.takeInvItem(player.inventory.selectedHotbarSlot, heldItem.count), false);
return;
}
}
if (WyHelper.isDebug() && key == Keyboard.KEY_Z && state) {
WyHelper.cheatCommand(player); WyHelper.cheatCommand(player);
return;
} }
} }
@Inject(method = "openChestScreen", at = @At("TAIL")) @Inject(method = "openChestScreen", at = @At("TAIL"))
public void openChestScreen(Inventory arg, CallbackInfo ci) { public void openChestScreen(Inventory arg, CallbackInfo ci) {
if(ModConfig.ADD_MORE_SOUNDS.get()) { if (ModConfig.ADD_MORE_SOUNDS.get()) {
Player player = (Player) (Object) this; Player player = (Player) (Object) this;
player.level.playSound(player, "random.chestopen", 0.3f, (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F); player.level.playSound(player, "random.chestopen", 0.3f, (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
} }
@ -38,9 +56,9 @@ public class ClientPlayerMixin {
@Inject(method = "closeContainer", at = @At("HEAD")) @Inject(method = "closeContainer", at = @At("HEAD"))
public void closeContainer(CallbackInfo ci) { public void closeContainer(CallbackInfo ci) {
if(ModConfig.ADD_MORE_SOUNDS.get()) { if (ModConfig.ADD_MORE_SOUNDS.get()) {
Player player = (Player) (Object) this; Player player = (Player) (Object) this;
if(player.container instanceof ChestContainer) { if (player.container instanceof ChestContainer) {
player.level.playSound(player, "random.chestclosed", 0.3f, (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F); player.level.playSound(player, "random.chestclosed", 0.3f, (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
} }
} }

View File

@ -0,0 +1,60 @@
package xyz.pixelatedw.finalbeta.mixin;
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;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.level.Level;
import net.minecraft.tile.FenceTile;
import net.minecraft.tile.Tile;
import net.minecraft.tile.material.Material;
import net.minecraft.util.maths.Box;
@Mixin(FenceTile.class)
public class FenceTileMixin extends Tile {
public FenceTileMixin(int i, Material j) {
super(i, j);
}
@Inject(method = "canPlaceAt", at = @At("HEAD"), cancellable = true)
public void canPlaceAt(Level arg, int i, int j, int k, CallbackInfoReturnable<Boolean> cir) {
cir.setReturnValue(true);
}
@Inject(method = "getCollisionShape", at = @At("HEAD"), cancellable = true)
public void getCollisionShape(Level level, int x, int y, int z, CallbackInfoReturnable<Box> cir) {
cir.setReturnValue(createFenceBox(level, x, y, z, false));
}
@Override
@Environment(EnvType.CLIENT)
public Box getOutlineShape(Level level, int x, int y, int z) {
return createFenceBox(level, x, y, z, true);
}
private Box createFenceBox(Level level, int x, int y, int z, boolean isOutline) {
boolean eastCheck = level.getMaterial(x + 1, y, z).isSolid();
boolean westCheck = level.getMaterial(x - 1, y, z).isSolid();
boolean southCheck = level.getMaterial(x, y, z + 1).isSolid();
boolean northCheck = level.getMaterial(x, y, z - 1).isSolid();
Box box = Box.create(westCheck ? 0 : 0.375f, 0.0f, northCheck ? 0.0f : 0.375f, eastCheck ? 1.0f : 0.625f, 1.0F, southCheck ? 1.0f : 0.625f);
box.minX += x;
box.minY += y;
box.minZ += z;
box.maxX += x;
box.maxY += y;
box.maxZ += z;
if (!isOutline) {
box.maxY += 0.5f;
}
return box;
}
}

View File

@ -0,0 +1,26 @@
package xyz.pixelatedw.finalbeta.mixin;
import org.spongepowered.asm.mixin.Mixin;
import net.minecraft.tile.GrassTile;
import net.minecraft.tile.Tile;
import net.minecraft.tile.material.Material;
@Mixin(GrassTile.class)
public class GrassTileMixin extends Tile {
public GrassTileMixin(int i, Material j) {
super(i, j);
}
@Override
public int getTextureForSide(int i) {
if (i == 1) {
return 0;
} else if (i == 0) {
return 2;
} else {
return this.tex;
}
}
}

View File

@ -0,0 +1,25 @@
package xyz.pixelatedw.finalbeta.mixin;
import java.util.List;
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;
import net.minecraft.entity.player.Player;
import net.minecraft.level.Level;
import net.minecraft.level.LevelMonsterSpawner;
import xyz.pixelatedw.finalbeta.ModConfig;
@Mixin(LevelMonsterSpawner.class)
public class LevelMonsterSpawnerMixin {
@Inject(method = "method_1869", at = @At("HEAD"), cancellable = true)
private static void nightmaresHandler(Level level, List<Player> playersList, CallbackInfoReturnable<Boolean> cir) {
if (ModConfig.REMOVE_NIGHTMARES.get()) {
cir.setReturnValue(false);
}
}
}

View File

@ -6,6 +6,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.animal.Chicken;
import net.minecraft.entity.animal.Pig; import net.minecraft.entity.animal.Pig;
import net.minecraft.item.ItemType; import net.minecraft.item.ItemType;
import xyz.pixelatedw.finalbeta.ModConfig; import xyz.pixelatedw.finalbeta.ModConfig;
@ -13,9 +14,19 @@ import xyz.pixelatedw.finalbeta.ModConfig;
@Mixin(LivingEntity.class) @Mixin(LivingEntity.class)
public class LivingEntityMixin { public class LivingEntityMixin {
@Inject(method = "setSize", at = @At("HEAD"), cancellable = true)
public void setSize(float f, float f1, CallbackInfo ci) {
LivingEntity entity = (LivingEntity) (Object) this;
if (entity instanceof Chicken) {
entity.width = 0.3F;
entity.height = 0.7F;
ci.cancel();
}
}
@Inject(method = "dropLoot", at = @At("TAIL")) @Inject(method = "dropLoot", at = @At("TAIL"))
public void dropLoot(CallbackInfo ci) { public void dropLoot(CallbackInfo ci) {
if(ModConfig.FIX_SADDLES_NOT_DROPPING.get()) { if (ModConfig.FIX_SADDLES_NOT_DROPPING.get()) {
LivingEntity entity = (LivingEntity) (Object) this; LivingEntity entity = (LivingEntity) (Object) this;
if (entity instanceof Pig && ((Pig) entity).isSaddled()) { if (entity instanceof Pig && ((Pig) entity).isSaddled()) {
entity.dropItem(ItemType.saddle.id, 1); entity.dropItem(ItemType.saddle.id, 1);

View File

@ -1,26 +0,0 @@
package xyz.pixelatedw.finalbeta.mixin;
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;
import net.minecraft.tile.Tile;
@Mixin(Tile.class)
public class TileMixin {
@Inject(method = "getTextureForSide(I)I", at = @At("HEAD"), cancellable = true)
public void getTextureForSide(int i, CallbackInfoReturnable<Integer> ci) {
Tile tile = (Tile) (Object) this;
if (tile.id == Tile.GRASS.id) {
if (i == 1) {
ci.setReturnValue(0);
} else if (i == 0) {
ci.setReturnValue(2);
} else {
ci.setReturnValue(tile.tex);
}
}
}
}

View File

@ -6,18 +6,90 @@ import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.client.colour.GrassColour; import net.minecraft.client.colour.GrassColour;
import net.minecraft.client.render.Tessellator; import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.TileRenderer; import net.minecraft.client.render.TileRenderer;
import net.minecraft.level.TileView;
import net.minecraft.tile.Tile; import net.minecraft.tile.Tile;
@Mixin(TileRenderer.class) @Mixin(TileRenderer.class)
public class TileRendererMixin { public class TileRendererMixin {
@Shadow
private TileView field_82;
@Shadow @Shadow
private int field_83; private int field_83;
// Fence renderer to handle it connecting with other non-fence blocks
@Inject(method = "method_78", at = @At("HEAD"), cancellable = true)
public void fenceRenderer(Tile tile, int x, int y, int z, CallbackInfoReturnable<Boolean> cir) {
TileRenderer renderer = (TileRenderer) (Object) this;
int var5 = 0;
float var6 = 0.375F;
float var7 = 0.625F;
tile.setBoundingBox(var6, 0.0F, var6, var7, 1.0F, var7);
renderer.method_76(tile, x, y, z);
var5 = 1;
int var8 = 0;
int var9 = 0;
if (this.field_82.getMaterial(x - 1, y, z).isSolid() || this.field_82.getMaterial(x + 1, y, z).isSolid()) {
var8 = 1;
}
if (this.field_82.getMaterial(x, y, z - 1).isSolid() || this.field_82.getMaterial(x, y, z + 1).isSolid()) {
var9 = 1;
}
int var10 = this.field_82.getMaterial(x - 1, y, z).isSolid() ? 1 : 0;
int var11 = this.field_82.getMaterial(x + 1, y, z).isSolid() ? 1 : 0;
int var12 = this.field_82.getMaterial(x, y, z - 1).isSolid() ? 1 : 0;
int var13 = this.field_82.getMaterial(x, y, z + 1).isSolid() ? 1 : 0;
if (var8 == 0 && var9 == 0) {
var8 = 1;
}
var6 = 0.4375F;
var7 = 0.5625F;
float var14 = 0.75F;
float var15 = 0.9375F;
float var16 = var10 != 0 ? 0.0F : var6;
float var17 = var11 != 0 ? 1.0F : var7;
float var18 = var12 != 0 ? 0.0F : var6;
float var19 = var13 != 0 ? 1.0F : var7;
if (var8 != 0) {
tile.setBoundingBox(var16, var14, var6, var17, var15, var7);
renderer.method_76(tile, x, y, z);
var5 = 1;
}
if (var9 != 0) {
tile.setBoundingBox(var6, var14, var18, var7, var15, var19);
renderer.method_76(tile, x, y, z);
var5 = 1;
}
var14 = 0.375F;
var15 = 0.5625F;
if (var8 != 0) {
tile.setBoundingBox(var16, var14, var6, var17, var15, var7);
renderer.method_76(tile, x, y, z);
var5 = 1;
}
if (var9 != 0) {
tile.setBoundingBox(var6, var14, var18, var7, var15, var19);
renderer.method_76(tile, x, y, z);
var5 = 1;
}
tile.setBoundingBox(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
cir.setReturnValue(var5 == 1 ? true : false);
}
// Grass block texture using side textures for top fix // Grass block texture using side textures for top fix
@Inject(method = "method_48", at = @At("HEAD"), cancellable = true) @Inject(method = "method_48", at = @At("HEAD"), cancellable = true)
public void grassBlockRenderer(Tile arg, int i, float f, CallbackInfo ci) { public void grassBlockRenderer(Tile arg, int i, float f, CallbackInfo ci) {

View File

@ -27,10 +27,15 @@
"FurnaceEntityMixin", "FurnaceEntityMixin",
"WorldRendererMixin", "WorldRendererMixin",
"VideoSettingsScreenMixin", "VideoSettingsScreenMixin",
"TileMixin", "GrassTileMixin",
"OverlayMixin" "OverlayMixin",
"BookshelfTileMixin",
"FenceTileMixin",
"LevelMonsterSpawnerMixin",
"BedTileMixin",
"BoatMixin"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": -1
} }
} }