Compare commits

..

25 Commits

Author SHA1 Message Date
3a323ad3f9 Update Version
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-12-15 11:22:05 -05:00
dd4694ec40 1.0.12 2020-12-15 11:21:36 -05:00
e04dc6ffe2 Fix Build
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-10-20 12:02:07 -04:00
a1b67ed622 1.0.11
Some checks failed
SlightlyVanilla/pipeline/head There was a failure building this commit
2020-10-20 11:51:45 -04:00
e7f639092b Update Gradle Version
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-09-13 00:07:13 -04:00
dc61f79b95 1.0.10
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-09-12 23:13:21 -04:00
f3ea21bea5 Use FabricEntityTypeBuilder
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-09-12 22:48:51 -04:00
b6614da325 Add Note Block Screen Tweak
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-09-12 22:46:06 -04:00
ed494fd52a Update To 1.16.2
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-08-24 18:08:54 -04:00
8342ef83ec Port To 1.16.1
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-06-24 18:48:38 -04:00
f030fce712 20w14a
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-04-03 12:00:02 -04:00
6fa51c4650 20w13b
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-03-26 11:45:35 -04:00
cabf4162ca Improve Dispenser Behavior
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-03-25 17:03:44 -04:00
c82406bb47 20w13a
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-03-25 15:13:07 -04:00
12920cdf8d 1.0.9
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
Disable Instant Nether Portal In Creative
2020-03-25 11:23:09 -04:00
484429ed23 Clean up code
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-03-22 13:54:49 -04:00
73d90bb2ff Add Annotations
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-03-21 15:27:29 -04:00
923a5936ee 1.0.8
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
Play Throw Sound
2020-03-21 14:43:33 -04:00
31bc26c4f8 Add Annotations
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-03-21 12:35:09 -04:00
2e76ebd416 Update Mappings
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-03-21 12:00:36 -04:00
f44cdd0699 1.0.7
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
Allow Leashing Villagers
2020-03-20 20:37:39 -04:00
003726ef22 1.0.6
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
Improve Instant Kill
2020-03-20 19:18:56 -04:00
c85c8798f1 Update Mixin
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-03-20 18:26:45 -04:00
4197534e8f 1.0.5
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
Crying Obsidian Nether Portal
2020-03-20 18:09:01 -04:00
b02c3982c1 Remove Unused Import
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
2020-03-20 14:06:39 -04:00
30 changed files with 589 additions and 118 deletions

4
.gitignore vendored
View File

@ -22,4 +22,6 @@ bin/
# fabric
run/
run/
remappedSrc/

View File

@ -1,5 +1,30 @@
# Changelog
**1.0.12**
* Allow Disabling Beds Setting Spawn
**1.0.11**
* Fix Loading On Client Without ModMenu
* Fix Loading On Server
**1.0.10**
* Add Note Block Screen Tweak
**1.0.9**
* Disable Instant Nether Portal In Creative
**1.0.8**
* Play Throw Sound
**1.0.7**
* Allow Leashing Villagers
**1.0.6**
* Improve Instant Kill
**1.0.5**
* Crying Obsidian Nether Portal
**1.0.4**
* Allow Opening Loot Chests In Spectator Mode

12
Jenkinsfile vendored
View File

@ -15,5 +15,17 @@ pipeline {
}
}
}
stage('Publish') {
when {
expression {
return sh(returnStdout: true, script: 'git tag --contains').trim().length() > 0
}
}
steps {
withCredentials([string(credentialsId: 'curseforge_key', variable: 'CURSEFORGE_KEY')]) {
sh './gradlew -Pcurseforge.api_key="${CURSEFORGE_KEY}" curseforge'
}
}
}
}
}

View File

@ -10,6 +10,10 @@ Suggest more tweaks in the issue tracker!
* Throwable Slimeballs
* Throwable Spawn Eggs
* Open Loot Chests In Spectator Mode
* Crying Obsidian Nether Portal
* Allow Leashing Villagers
* Disable Instant Nether Portal In Creative
* Add Note Block Screen
## Changelog
[View Changelog](CHANGELOG.md)

View File

@ -1,5 +1,5 @@
plugins {
id 'fabric-loom' version '0.2.7-SNAPSHOT'
id 'fabric-loom' version '0.4-SNAPSHOT'
id 'com.matthewprenger.cursegradle' version '1.4.0'
}
@ -9,7 +9,8 @@ compileJava {
}
archivesBaseName = project.archives_base_name
version = project.mod_version as Object
def mod_version = project.mod_version as Object
version = "${mod_version}+${project.minecraft_version}"
group = project.maven_group as Object
minecraft {
@ -30,18 +31,18 @@ dependencies {
modImplementation "me.shedaniel.cloth:config-2:${project.cloth_config_version}"
include "me.shedaniel.cloth:config-2:${project.cloth_config_version}"
modImplementation "me.sargunvohra.mcmods:autoconfig1u:${project.auto_config_version}"
include "me.sargunvohra.mcmods:autoconfig1u:${project.auto_config_version}"
modImplementation "io.github.prospector:modmenu:${project.mod_menu_version}"
modImplementation "me.sargunvohra.mcmods:autoconfig1u:${project.autoconfig_version}"
include "me.sargunvohra.mcmods:autoconfig1u:${project.autoconfig_version}"
modImplementation "io.github.prospector:modmenu:${project.modmenu_version}"
}
processResources {
inputs.property 'version', version
inputs.property 'version', project.version
inputs.property 'name', rootProject.name
from(sourceSets.main.resources.srcDirs) {
include 'fabric.mod.json'
expand 'version': version, 'name': rootProject.name
expand 'version': project.version, 'name': rootProject.name
}
from(sourceSets.main.resources.srcDirs) {
@ -88,7 +89,7 @@ if (project.hasProperty('curseforge.api_key')) {
addGameVersion project.simple_minecraft_version
addGameVersion 'Fabric'
mainArtifact(remapJar) {
displayName = "SlightlyVanilla v${version} for ${project.minecraft_version}"
displayName = "SlightlyVanilla v${mod_version} for ${project.minecraft_version}"
}
afterEvaluate {
uploadTask.dependsOn('remapJar')

View File

@ -3,20 +3,20 @@ org.gradle.jvmargs = -Xmx1G
# Fabric Properties
# check these on https://fabricmc.net/use
minecraft_version = 20w12a
minecraft_version = 1.16.4
curseforge_id = 368420
simple_minecraft_version = 1.16-Snapshot
yarn_build = 14
fabric_loader_version = 0.7.8+build.189
simple_minecraft_version = 1.16.4
yarn_build = 7
fabric_loader_version = 0.10.8
# Mod Properties
mod_version = 1.0.4
mod_version = 1.0.12
maven_group = com.thebrokenrail
archives_base_name = slightlyvanilla
# Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
fabric_api_version = 0.5.5+build.311-1.16
cloth_config_version = 3.1.0-unstable
auto_config_version = 1.2.4
mod_menu_version = 1.10.2+build.1
fabric_api_version = 0.28.1+1.16
modmenu_version = 1.14.6+build.31
cloth_config_version = 4.7.0-unstable
autoconfig_version = 3.2.0-unstable

View File

@ -3,6 +3,9 @@ package com.thebrokenrail.slightlyvanilla;
import me.sargunvohra.mcmods.autoconfig1u.ConfigData;
import me.sargunvohra.mcmods.autoconfig1u.annotation.Config;
import me.sargunvohra.mcmods.autoconfig1u.annotation.ConfigEntry;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
@Config(name = SlightlyVanilla.NAMESPACE)
public class ModConfig implements ConfigData {
@ -13,6 +16,12 @@ public class ModConfig implements ConfigData {
@ConfigEntry.Gui.CollapsibleObject(startExpanded = true)
public ThrowableOption throwableSpawnEggs = new ThrowableOption(true, false);
public boolean openLootChestsInSpectatorMode = true;
public boolean cryingObsidianNetherPortal = true;
public boolean allowLeashingVillagers = true;
public boolean disableInstantNetherPortalInCreative = true;
@Environment(EnvType.CLIENT)
public boolean noteBlockScreen = true;
public boolean bedsSetSpawn = true;
public static class ThrowableOption {
public boolean player;

View File

@ -1,28 +1,29 @@
package com.thebrokenrail.slightlyvanilla;
import com.thebrokenrail.slightlyvanilla.dispenser.SlimeballDispenserBehavior;
import com.thebrokenrail.slightlyvanilla.dispenser.SpawnEggDispenserBehavior;
import com.thebrokenrail.slightlyvanilla.entity.SlimeballEntity;
import com.thebrokenrail.slightlyvanilla.entity.SpawnEggEntity;
import me.sargunvohra.mcmods.autoconfig1u.AutoConfig;
import me.sargunvohra.mcmods.autoconfig1u.serializer.GsonConfigSerializer;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.entity.FabricEntityTypeBuilder;
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder;
import net.fabricmc.fabric.api.tag.TagRegistry;
import net.minecraft.block.Block;
import net.minecraft.block.DispenserBlock;
import net.minecraft.block.dispenser.ItemDispenserBehavior;
import net.minecraft.block.dispenser.ProjectileDispenserBehavior;
import net.minecraft.entity.EntityCategory;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnType;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.entity.SpawnGroup;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Items;
import net.minecraft.item.SpawnEggItem;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.tag.Tag;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPointer;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Position;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
import java.util.Random;
public class SlightlyVanilla implements ModInitializer {
public static final String NAMESPACE = "slightlyvanilla";
@ -30,6 +31,8 @@ public class SlightlyVanilla implements ModInitializer {
public static EntityType<SlimeballEntity> SLIMEBALL_ENTITY;
public static EntityType<SpawnEggEntity> SPAWN_EGG_ENTITY;
public static final Tag<Block> NETHER_PORTAL_FRAME_BLOCKS_TAG = TagRegistry.block(new Identifier(NAMESPACE, "nether_portal_frame_blocks"));
public static ModConfig getConfig() {
return AutoConfig.getConfigHolder(ModConfig.class).getConfig();
}
@ -38,51 +41,20 @@ public class SlightlyVanilla implements ModInitializer {
public void onInitialize() {
AutoConfig.register(ModConfig.class, GsonConfigSerializer::new);
SLIMEBALL_ENTITY = FabricEntityTypeBuilder.create(EntityCategory.MISC, (EntityType.EntityFactory<SlimeballEntity>) SlimeballEntity::new).size(EntityDimensions.fixed(0.25f, 0.25f)).build();
SPAWN_EGG_ENTITY = FabricEntityTypeBuilder.create(EntityCategory.MISC, (EntityType.EntityFactory<SpawnEggEntity>) SpawnEggEntity::new).size(EntityDimensions.fixed(0.25f, 0.25f)).build();
SLIMEBALL_ENTITY = FabricEntityTypeBuilder.create(SpawnGroup.MISC, (EntityType.EntityFactory<SlimeballEntity>) SlimeballEntity::new).dimensions(new EntityDimensions(0.25f, 0.25f, true)).build();
SPAWN_EGG_ENTITY = FabricEntityTypeBuilder.create(SpawnGroup.MISC, (EntityType.EntityFactory<SpawnEggEntity>) SpawnEggEntity::new).dimensions(new EntityDimensions(0.25f, 0.25f, true)).build();
Registry.register(Registry.ENTITY_TYPE, new Identifier(NAMESPACE, "slimeball"), SLIMEBALL_ENTITY);
Registry.register(Registry.ENTITY_TYPE, new Identifier(NAMESPACE, "spawn_egg"), SPAWN_EGG_ENTITY);
DispenserBlock.registerBehavior(Items.SLIME_BALL, (pointer, stack) -> {
if (getConfig().throwableSlimeballs.dispenser) {
return new ProjectileDispenserBehavior() {
@Override
protected ProjectileEntity createProjectile(World position, Position stack, ItemStack itemStack) {
SlimeballEntity entity = new SlimeballEntity(position, stack.getX(), stack.getY(), stack.getZ());
entity.setItem(itemStack);
return entity;
}
}.dispense(pointer, stack);
} else {
return new ItemDispenserBehavior().dispense(pointer, stack);
}
});
DispenserBlock.registerBehavior(Items.SLIME_BALL, new SlimeballDispenserBehavior());
for (SpawnEggItem spawnEgg : SpawnEggItem.getAll()) {
DispenserBlock.registerBehavior(spawnEgg, (pointer, stack) -> {
if (getConfig().throwableSpawnEggs.dispenser) {
return new ProjectileDispenserBehavior() {
@Override
protected ProjectileEntity createProjectile(World position, Position stack, ItemStack itemStack) {
SpawnEggEntity entity = new SpawnEggEntity(position, stack.getX(), stack.getY(), stack.getZ());
entity.setItem(itemStack);
return entity;
}
}.dispense(pointer, stack);
} else {
return new ItemDispenserBehavior() {
@Override
protected ItemStack dispenseSilently(BlockPointer pointer, ItemStack stack) {
Direction direction = pointer.getBlockState().get(DispenserBlock.FACING);
EntityType<?> entityType = ((SpawnEggItem)stack.getItem()).getEntityType(stack.getTag());
entityType.spawnFromItemStack(pointer.getWorld(), stack, null, pointer.getBlockPos().offset(direction), SpawnType.DISPENSER, direction != Direction.UP, false);
stack.decrement(1);
return stack;
}
}.dispense(pointer, stack);
}
});
DispenserBlock.registerBehavior(spawnEgg, new SpawnEggDispenserBehavior());
}
}
public static void playThrowSound(PlayerEntity user) {
user.getEntityWorld().playSound(null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENTITY_SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (new Random().nextFloat() * 0.4F + 0.8F));
}
}

View File

@ -0,0 +1,18 @@
package com.thebrokenrail.slightlyvanilla.client;
import com.thebrokenrail.slightlyvanilla.ModConfig;
import io.github.prospector.modmenu.api.ConfigScreenFactory;
import io.github.prospector.modmenu.api.ModMenuApi;
import me.sargunvohra.mcmods.autoconfig1u.AutoConfig;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.screen.Screen;
@SuppressWarnings("unused")
@Environment(EnvType.CLIENT)
public class ModMenu implements ModMenuApi {
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return (ConfigScreenFactory<Screen>) screen -> AutoConfig.getConfigScreen(ModConfig.class, screen).get();
}
}

View File

@ -1,32 +1,20 @@
package com.thebrokenrail.slightlyvanilla.client;
import com.thebrokenrail.slightlyvanilla.SlightlyVanilla;
import com.thebrokenrail.slightlyvanilla.ModConfig;
import com.thebrokenrail.slightlyvanilla.entity.SlimeballEntity;
import com.thebrokenrail.slightlyvanilla.entity.SpawnEggEntity;
import io.github.prospector.modmenu.api.ConfigScreenFactory;
import io.github.prospector.modmenu.api.ModMenuApi;
import me.sargunvohra.mcmods.autoconfig1u.AutoConfig;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.render.entity.FlyingItemEntityRenderer;
@SuppressWarnings("unused")
public class SlightlyVanillaClient implements ClientModInitializer, ModMenuApi {
@Environment(EnvType.CLIENT)
public class SlightlyVanillaClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
EntityRendererRegistry.INSTANCE.register(SlightlyVanilla.SLIMEBALL_ENTITY, (entityRenderDispatcher, context) -> new FlyingItemEntityRenderer<SlimeballEntity>(entityRenderDispatcher, context.getItemRenderer()));
EntityRendererRegistry.INSTANCE.register(SlightlyVanilla.SPAWN_EGG_ENTITY, (entityRenderDispatcher, context) -> new FlyingItemEntityRenderer<SpawnEggEntity>(entityRenderDispatcher, context.getItemRenderer()));
}
@Override
public String getModId() {
return SlightlyVanilla.NAMESPACE;
}
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return (ConfigScreenFactory<Screen>) screen -> AutoConfig.getConfigScreen(ModConfig.class, screen).get();
}
}

View File

@ -0,0 +1,144 @@
package com.thebrokenrail.slightlyvanilla.client.screen;
import com.mojang.blaze3d.systems.RenderSystem;
import com.thebrokenrail.slightlyvanilla.SlightlyVanilla;
import com.thebrokenrail.slightlyvanilla.mixin.ScreenHandlerAccessor;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.SliderWidget;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket;
import net.minecraft.screen.ScreenHandlerContext;
import net.minecraft.state.property.Properties;
import net.minecraft.text.LiteralText;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import java.util.function.BiFunction;
@Environment(EnvType.CLIENT)
public class NoteBlockScreen extends Screen {
private static class NoteSliderWidget extends SliderWidget {
private final ScreenHandlerContext context;
public NoteSliderWidget(ScreenHandlerContext context, int x, int y, int width, int height) {
super(x, y, width, height, LiteralText.EMPTY, (double) getNote(context) / getMax());
this.context = context;
updateMessage();
}
private static double getMax() {
return (double) Properties.NOTE.getValues().size() - 1;
}
@SuppressWarnings("OptionalGetWithoutIsPresent")
private static int getNote(ScreenHandlerContext context) {
return context.run((BiFunction<World, BlockPos, Integer>) (world, pos) -> world.getBlockState(pos).get(Properties.NOTE)).get();
}
private int toNote() {
return (int) (value * getMax());
}
@Override
protected void updateMessage() {
int note = toNote();
setMessage(new TranslatableText("text." + SlightlyVanilla.NAMESPACE + ".noteblock_screen_slider", note, new TranslatableText("text." + SlightlyVanilla.NAMESPACE + ".noteblock_note." + note)));
}
@Override
protected void applyValue() {
context.run((world, blockPos) -> {
BlockState target = world.getBlockState(blockPos);
int currentNote = target.get(Properties.NOTE);
int targetNote = toNote();
int amount;
if (targetNote >= currentNote) {
amount = targetNote - currentNote;
} else {
amount = ((int) getMax()) - currentNote + 1 + targetNote;
}
MinecraftClient client = MinecraftClient.getInstance();
assert client != null;
assert client.getNetworkHandler() != null;
BlockHitResult hitResult = new BlockHitResult(Vec3d.ofCenter(blockPos), Direction.UP, blockPos, false);
for (int i = 0; i < amount; i++) {
client.getNetworkHandler().sendPacket(new PlayerInteractBlockC2SPacket(Hand.MAIN_HAND, hitResult));
}
world.setBlockState(blockPos, target.with(Properties.NOTE, targetNote));
});
}
}
private static final Identifier TEXTURE = new Identifier(SlightlyVanilla.NAMESPACE, "textures/gui/noteblock.png");
private final ScreenHandlerContext context;
public NoteBlockScreen(ScreenHandlerContext context) {
super(Blocks.NOTE_BLOCK.getName());
passEvents = true;
this.context = context;
}
@Override
protected void init() {
super.init();
int sliderWidth = BACKGROUND_WIDTH - 36;
int sliderHeight = 20;
addButton(new NoteSliderWidget(context, width / 2 - sliderWidth / 2, (height / 2) - (sliderHeight / 2) + 4, sliderWidth, sliderHeight));
}
private static final int BACKGROUND_WIDTH = 176;
private static final int BACKGROUND_HEIGHT = 60;
private static final int TITLE_X_OFFSET = 8;
private static final int TITLE_Y_OFFSEt = 6;
@Override
public void renderBackground(MatrixStack matrices) {
super.renderBackground(matrices);
//noinspection deprecation
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
assert client != null;
client.getTextureManager().bindTexture(TEXTURE);
int centerX = width / 2;
int centerY = height / 2;
drawTexture(matrices, centerX - (BACKGROUND_WIDTH / 2), centerY - (BACKGROUND_HEIGHT / 2), 0, 0, BACKGROUND_WIDTH, BACKGROUND_HEIGHT);
int titleX = centerX - (BACKGROUND_WIDTH / 2) + TITLE_X_OFFSET;
int titleY = centerY - (BACKGROUND_HEIGHT / 2) + TITLE_Y_OFFSEt;
textRenderer.draw(matrices, title, titleX, titleY, 4210752);
}
@Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
renderBackground(matrices);
super.render(matrices, mouseX, mouseY, delta);
}
@Override
public void tick() {
super.tick();
assert client != null;
if (!ScreenHandlerAccessor.callCanUse(context, client.player, Blocks.NOTE_BLOCK)) {
assert client.player != null;
client.player.closeScreen();
}
}
}

View File

@ -0,0 +1,35 @@
package com.thebrokenrail.slightlyvanilla.dispenser;
import com.thebrokenrail.slightlyvanilla.SlightlyVanilla;
import com.thebrokenrail.slightlyvanilla.entity.SlimeballEntity;
import net.minecraft.block.dispenser.DispenserBehavior;
import net.minecraft.block.dispenser.ItemDispenserBehavior;
import net.minecraft.block.dispenser.ProjectileDispenserBehavior;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPointer;
import net.minecraft.util.math.Position;
import net.minecraft.world.World;
public class SlimeballDispenserBehavior implements DispenserBehavior {
private static class Default extends ItemDispenserBehavior {
}
private static class Modified extends ProjectileDispenserBehavior {
@Override
protected ProjectileEntity createProjectile(World position, Position stack, ItemStack itemStack) {
SlimeballEntity entity = new SlimeballEntity(position, stack.getX(), stack.getY(), stack.getZ());
entity.setItem(itemStack);
return entity;
}
}
@Override
public ItemStack dispense(BlockPointer pointer, ItemStack stack) {
if (SlightlyVanilla.getConfig().throwableSlimeballs.dispenser) {
return new Modified().dispense(pointer, stack);
} else {
return new Default().dispense(pointer, stack);
}
}
}

View File

@ -0,0 +1,48 @@
package com.thebrokenrail.slightlyvanilla.dispenser;
import com.thebrokenrail.slightlyvanilla.SlightlyVanilla;
import com.thebrokenrail.slightlyvanilla.entity.SpawnEggEntity;
import net.minecraft.block.DispenserBlock;
import net.minecraft.block.dispenser.DispenserBehavior;
import net.minecraft.block.dispenser.ItemDispenserBehavior;
import net.minecraft.block.dispenser.ProjectileDispenserBehavior;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.SpawnEggItem;
import net.minecraft.util.math.BlockPointer;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Position;
import net.minecraft.world.World;
public class SpawnEggDispenserBehavior implements DispenserBehavior {
private static class Default extends ItemDispenserBehavior {
@Override
protected ItemStack dispenseSilently(BlockPointer pointer, ItemStack stack) {
Direction direction = pointer.getBlockState().get(DispenserBlock.FACING);
EntityType<?> entityType = ((SpawnEggItem)stack.getItem()).getEntityType(stack.getTag());
entityType.spawnFromItemStack(pointer.getWorld(), stack, null, pointer.getBlockPos().offset(direction), SpawnReason.DISPENSER, direction != Direction.UP, false);
stack.decrement(1);
return stack;
}
}
private static class Modified extends ProjectileDispenserBehavior {
@Override
protected ProjectileEntity createProjectile(World position, Position stack, ItemStack itemStack) {
SpawnEggEntity entity = new SpawnEggEntity(position, stack.getX(), stack.getY(), stack.getZ());
entity.setItem(itemStack);
return entity;
}
}
@Override
public ItemStack dispense(BlockPointer pointer, ItemStack stack) {
if (SlightlyVanilla.getConfig().throwableSpawnEggs.dispenser) {
return new Modified().dispense(pointer, stack);
} else {
return new Default().dispense(pointer, stack);
}
}
}

View File

@ -15,6 +15,7 @@ import net.minecraft.particle.ParticleTypes;
import net.minecraft.util.hit.HitResult;
import net.minecraft.world.World;
@SuppressWarnings("unused")
public class SlimeballEntity extends ThrownItemEntity {
public SlimeballEntity(EntityType<SlimeballEntity> entityType, World world) {
super(entityType, world);
@ -28,6 +29,11 @@ public class SlimeballEntity extends ThrownItemEntity {
super(SlightlyVanilla.SLIMEBALL_ENTITY, x, y, z, world);
}
public SlimeballEntity(World world) {
super(SlightlyVanilla.SLIMEBALL_ENTITY, world);
}
@Override
protected Item getDefaultItem() {
return Items.SLIME_BALL;
}
@ -43,15 +49,16 @@ public class SlimeballEntity extends ThrownItemEntity {
ParticleEffect particleEffect = getParticleParameters();
for (int i = 0; i < 8; ++i) {
world.addParticle(particleEffect, getX(), getY(), getZ(), 0.0D, 0.0D, 0.0D);
getEntityWorld().addParticle(particleEffect, getX(), getY(), getZ(), 0.0D, 0.0D, 0.0D);
}
}
}
@Override
protected void onCollision(HitResult hitResult) {
super.onCollision(hitResult);
if (!world.isClient()) {
world.sendEntityStatus(this, (byte) 3);
if (!getEntityWorld().isClient()) {
getEntityWorld().sendEntityStatus(this, (byte) 3);
remove();
}
}

View File

@ -5,7 +5,7 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.SpawnType;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.projectile.thrown.ThrownItemEntity;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
@ -15,9 +15,11 @@ import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket;
import net.minecraft.particle.ItemStackParticleEffect;
import net.minecraft.particle.ParticleEffect;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.hit.HitResult;
import net.minecraft.world.World;
@SuppressWarnings("unused")
public class SpawnEggEntity extends ThrownItemEntity {
public SpawnEggEntity(EntityType<SpawnEggEntity> entityType, World world) {
super(entityType, world);
@ -31,6 +33,11 @@ public class SpawnEggEntity extends ThrownItemEntity {
super(SlightlyVanilla.SPAWN_EGG_ENTITY, x, y, z, world);
}
public SpawnEggEntity(World world) {
super(SlightlyVanilla.SPAWN_EGG_ENTITY, world);
}
@Override
protected Item getDefaultItem() {
return Items.PIG_SPAWN_EGG;
}
@ -46,17 +53,18 @@ public class SpawnEggEntity extends ThrownItemEntity {
ParticleEffect particleEffect = getParticleParameters();
for (int i = 0; i < 8; ++i) {
world.addParticle(particleEffect, getX(), getY(), getZ(), 0.0D, 0.0D, 0.0D);
getEntityWorld().addParticle(particleEffect, getX(), getY(), getZ(), 0.0D, 0.0D, 0.0D);
}
}
}
@Override
protected void onCollision(HitResult hitResult) {
super.onCollision(hitResult);
if (!world.isClient()) {
world.sendEntityStatus(this, (byte) 3);
if (!getEntityWorld().isClient()) {
getEntityWorld().sendEntityStatus(this, (byte) 3);
EntityType<?> entityType = ((SpawnEggItem) getStack().getItem()).getEntityType(getStack().getTag());
entityType.spawnFromItemStack(world, getItem(), null, getBlockPos(), SpawnType.SPAWN_EGG, false, false);
entityType.spawnFromItemStack((ServerWorld) getEntityWorld(), getItem(), null, getBlockPos(), SpawnReason.SPAWN_EGG, false, false);
remove();
}
}

View File

@ -0,0 +1,27 @@
package com.thebrokenrail.slightlyvanilla.mixin;
import com.thebrokenrail.slightlyvanilla.SlightlyVanilla;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.passive.MerchantEntity;
import net.minecraft.entity.passive.PassiveEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.World;
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;
@SuppressWarnings("unused")
@Mixin(MerchantEntity.class)
public abstract class MixinAbstractTraderEntity extends PassiveEntity {
protected MixinAbstractTraderEntity(EntityType<? extends PassiveEntity> entityType, World world) {
super(entityType, world);
}
@Inject(at = @At("HEAD"), method = "canBeLeashedBy", cancellable = true)
public void canBeLeashedBy(PlayerEntity player, CallbackInfoReturnable<Boolean> info) {
if (SlightlyVanilla.getConfig().allowLeashingVillagers) {
info.setReturnValue(super.canBeLeashedBy(player));
}
}
}

View File

@ -3,6 +3,8 @@ package com.thebrokenrail.slightlyvanilla.mixin;
import com.thebrokenrail.slightlyvanilla.SlightlyVanilla;
import com.thebrokenrail.slightlyvanilla.entity.SlimeballEntity;
import com.thebrokenrail.slightlyvanilla.entity.SpawnEggEntity;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
@ -20,6 +22,7 @@ public class MixinClientPlayNetworkHandler {
@Shadow
private ClientWorld world;
@Environment(EnvType.CLIENT)
@Inject(method = "onEntitySpawn", at = @At(value = "TAIL"))
public void onEntitySpawn(EntitySpawnS2CPacket packet, CallbackInfo info) {
EntityType<?> entityType = packet.getEntityTypeId();

View File

@ -0,0 +1,39 @@
package com.thebrokenrail.slightlyvanilla.mixin;
import com.thebrokenrail.slightlyvanilla.SlightlyVanilla;
import com.thebrokenrail.slightlyvanilla.client.screen.NoteBlockScreen;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.Blocks;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.network.ClientPlayerInteractionManager;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.screen.ScreenHandlerContext;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
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.CallbackInfoReturnable;
@Environment(EnvType.CLIENT)
@Mixin(ClientPlayerInteractionManager.class)
public class MixinClientPlayerInteractionManager {
@Shadow
@Final
private MinecraftClient client;
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getStackInHand(Lnet/minecraft/util/Hand;)Lnet/minecraft/item/ItemStack;", ordinal = 0), method = "interactBlock", cancellable = true)
public void interactBlock(ClientPlayerEntity player, ClientWorld world, Hand hand, BlockHitResult hitResult, CallbackInfoReturnable<ActionResult> info) {
if (!player.isSpectator() && SlightlyVanilla.getConfig().noteBlockScreen && world.getBlockState(hitResult.getBlockPos()).getBlock() == Blocks.NOTE_BLOCK) {
NoteBlockScreen screen = new NoteBlockScreen(ScreenHandlerContext.create(world, hitResult.getBlockPos()));
client.openScreen(screen);
info.setReturnValue(ActionResult.SUCCESS);
}
}
}

View File

@ -2,7 +2,6 @@ package com.thebrokenrail.slightlyvanilla.mixin;
import com.thebrokenrail.slightlyvanilla.SlightlyVanilla;
import com.thebrokenrail.slightlyvanilla.entity.SlimeballEntity;
import net.minecraft.block.ChestBlock;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@ -23,6 +22,7 @@ public class MixinItem {
public void use(World world, PlayerEntity playerEntity, Hand hand, CallbackInfoReturnable<TypedActionResult<ItemStack>> info) {
ItemStack stack = playerEntity.getStackInHand(hand);
if (stack.getItem() == Items.SLIME_BALL && SlightlyVanilla.getConfig().throwableSlimeballs.player) {
SlightlyVanilla.playThrowSound(playerEntity);
if (!world.isClient()) {
SlimeballEntity entity = new SlimeballEntity(world, playerEntity);
entity.setItem(stack);

View File

@ -0,0 +1,22 @@
package com.thebrokenrail.slightlyvanilla.mixin;
import com.thebrokenrail.slightlyvanilla.SlightlyVanilla;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.minecraft.world.dimension.AreaHelper;
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;
@SuppressWarnings("unused")
@Mixin(AreaHelper.class)
public class MixinNetherPortalBlockAreaHelper {
@Inject(at = @At("HEAD"), method = "method_30487", cancellable = true)
private static void isValidFrameBlock(BlockState state, BlockView world, BlockPos pos, CallbackInfoReturnable<Boolean> info) {
if (SlightlyVanilla.getConfig().cryingObsidianNetherPortal) {
info.setReturnValue(state.isIn(SlightlyVanilla.NETHER_PORTAL_FRAME_BLOCKS_TAG));
}
}
}

View File

@ -1,26 +1,34 @@
package com.thebrokenrail.slightlyvanilla.mixin;
import com.thebrokenrail.slightlyvanilla.SlightlyVanilla;
import net.minecraft.entity.Entity;
import net.minecraft.entity.boss.dragon.EnderDragonPart;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.player.PlayerAbilities;
import net.minecraft.entity.player.PlayerEntity;
import org.objectweb.asm.Opcodes;
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.CallbackInfo;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.Redirect;
@SuppressWarnings("unused")
@Mixin(PlayerEntity.class)
public class MixinPlayerEntity {
@Inject(at = @At("HEAD"), method = "attack", cancellable = true)
public void attack(Entity target, CallbackInfo info) {
if (SlightlyVanilla.getConfig().instantKillInCreative && target.isAttackable()) {
if (target instanceof EnderDragonPart) {
target = ((EnderDragonPart)target).owner;
}
//noinspection ConstantConditions
target.damage(DamageSource.player((PlayerEntity) (Object) this), Float.MAX_VALUE);
@ModifyArg(at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;damage(Lnet/minecraft/entity/damage/DamageSource;F)Z"), method = "attack", index = 1)
public float changeDamage(DamageSource source, float amount) {
//noinspection ConstantConditions
if (SlightlyVanilla.getConfig().instantKillInCreative && ((PlayerEntity) (Object) this).isCreative()) {
return Float.MAX_VALUE;
} else {
return amount;
}
}
@Redirect(at = @At(value = "FIELD", opcode = Opcodes.GETFIELD, target = "Lnet/minecraft/entity/player/PlayerAbilities;invulnerable:Z"), method = "getMaxNetherPortalTime")
public boolean adjustMaxNetherPortalTime(PlayerAbilities playerAbilities) {
if (SlightlyVanilla.getConfig().disableInstantNetherPortalInCreative) {
return false;
} else {
return playerAbilities.invulnerable;
}
}
}

View File

@ -2,21 +2,31 @@ package com.thebrokenrail.slightlyvanilla.mixin;
import com.thebrokenrail.slightlyvanilla.SlightlyVanilla;
import net.minecraft.block.RespawnAnchorBlock;
import net.minecraft.world.dimension.Dimension;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
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.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@SuppressWarnings("unused")
@Mixin(RespawnAnchorBlock.class)
public class MixinRespawnAnchorBlock {
@Redirect(at = @At(value = "INVOKE", target = "Lnet/minecraft/world/dimension/Dimension;getType()Lnet/minecraft/world/dimension/DimensionType;", ordinal = 0), method = "onUse")
public DimensionType getDimension(Dimension dimension) {
@Inject(at = @At("HEAD"), method = "isNether", cancellable = true)
private static void isNether(World world, CallbackInfoReturnable<Boolean> info) {
if (SlightlyVanilla.getConfig().useRespawnAnchorInAnyDimension) {
return DimensionType.THE_NETHER;
info.setReturnValue(true);
}
}
@Redirect(at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;getSpawnPointPosition()Lnet/minecraft/util/math/BlockPos;"), method = "onUse")
public BlockPos getSpawnPointPosition(ServerPlayerEntity serverPlayerEntity) {
if (SlightlyVanilla.getConfig().useRespawnAnchorInAnyDimension && serverPlayerEntity.getSpawnPointPosition() == null) {
return new BlockPos(0, 512, 0);
} else {
return dimension.getType();
return serverPlayerEntity.getSpawnPointPosition();
}
}
}

View File

@ -0,0 +1,20 @@
package com.thebrokenrail.slightlyvanilla.mixin;
import com.thebrokenrail.slightlyvanilla.SlightlyVanilla;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ServerPlayerEntity.class)
public class MixinServerPlayerEntity {
@Redirect(at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;setSpawnPoint(Lnet/minecraft/util/registry/RegistryKey;Lnet/minecraft/util/math/BlockPos;FZZ)V"), method = "trySleep")
public void setSpawnPoint(ServerPlayerEntity obj, RegistryKey<World> dimension, BlockPos pos, float angle, boolean spawnPointSet, boolean bl) {
if (SlightlyVanilla.getConfig().bedsSetSpawn) {
obj.setSpawnPoint(dimension, pos, angle, spawnPointSet, bl);
}
}
}

View File

@ -21,6 +21,7 @@ public class MixinSpawnEggItem {
public void use(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable<TypedActionResult<ItemStack>> info) {
if (SlightlyVanilla.getConfig().throwableSpawnEggs.player && info.getReturnValue().getResult() == ActionResult.PASS) {
ItemStack stack = user.getStackInHand(hand);
SlightlyVanilla.playThrowSound(user);
if (!world.isClient()) {
SpawnEggEntity entity = new SpawnEggEntity(world, user);
entity.setItem(stack);

View File

@ -0,0 +1,19 @@
package com.thebrokenrail.slightlyvanilla.mixin;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.Block;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ScreenHandlerContext;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Environment(EnvType.CLIENT)
@Mixin(ScreenHandler.class)
public interface ScreenHandlerAccessor {
@Invoker
static boolean callCanUse(ScreenHandlerContext context, PlayerEntity player, Block block) {
throw new UnsupportedOperationException();
}
}

View File

@ -9,6 +9,37 @@
"text.autoconfig.slightlyvanilla.option.throwableSpawnEggs.player": "Player",
"text.autoconfig.slightlyvanilla.option.throwableSpawnEggs.dispenser": "Dispenser",
"text.autoconfig.slightlyvanilla.option.openLootChestsInSpectatorMode": "Open Loot Chests In Spectator Mode",
"text.autoconfig.slightlyvanilla.option.cryingObsidianNetherPortal": "Crying Obsidian Nether Portal",
"text.autoconfig.slightlyvanilla.option.allowLeashingVillagers": "Allow Leashing Villagers",
"text.autoconfig.slightlyvanilla.option.disableInstantNetherPortalInCreative": "Disable Instant Nether Portal In Creative",
"text.autoconfig.slightlyvanilla.option.noteBlockScreen": "Add Note Block Screen",
"text.autoconfig.slightlyvanilla.option.bedsSetSpawn": "Beds Set Spawn",
"entity.slightlyvanilla.slimeball": "Slimeball",
"entity.slightlyvanilla.spawn_egg": "Spawn Egg"
"entity.slightlyvanilla.spawn_egg": "Spawn Egg",
"text.slightlyvanilla.noteblock_screen_slider": "Note: %s (%s)",
"text.slightlyvanilla.noteblock_note.0": "F#",
"text.slightlyvanilla.noteblock_note.1": "G",
"text.slightlyvanilla.noteblock_note.2": "G#",
"text.slightlyvanilla.noteblock_note.3": "A",
"text.slightlyvanilla.noteblock_note.4": "A#",
"text.slightlyvanilla.noteblock_note.5": "B",
"text.slightlyvanilla.noteblock_note.6": "C",
"text.slightlyvanilla.noteblock_note.7": "C#",
"text.slightlyvanilla.noteblock_note.8": "D",
"text.slightlyvanilla.noteblock_note.9": "D#",
"text.slightlyvanilla.noteblock_note.10": "E",
"text.slightlyvanilla.noteblock_note.11": "F",
"text.slightlyvanilla.noteblock_note.12": "F#",
"text.slightlyvanilla.noteblock_note.13": "G",
"text.slightlyvanilla.noteblock_note.14": "G#",
"text.slightlyvanilla.noteblock_note.15": "A",
"text.slightlyvanilla.noteblock_note.16": "A#",
"text.slightlyvanilla.noteblock_note.17": "B",
"text.slightlyvanilla.noteblock_note.18": "C",
"text.slightlyvanilla.noteblock_note.19": "C#",
"text.slightlyvanilla.noteblock_note.20": "D",
"text.slightlyvanilla.noteblock_note.21": "D#",
"text.slightlyvanilla.noteblock_note.22": "E",
"text.slightlyvanilla.noteblock_note.23": "F",
"text.slightlyvanilla.noteblock_note.24": "F#"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@ -0,0 +1,7 @@
{
"replace": false,
"values": [
"minecraft:obsidian",
"minecraft:crying_obsidian"
]
}

View File

@ -23,7 +23,7 @@
"com.thebrokenrail.slightlyvanilla.client.SlightlyVanillaClient"
],
"modmenu": [
"com.thebrokenrail.slightlyvanilla.client.SlightlyVanillaClient"
"com.thebrokenrail.slightlyvanilla.client.ModMenu"
]
},
"mixins": [
@ -33,5 +33,11 @@
"fabricloader": ">=0.7.4",
"fabric": "*",
"minecraft": "1.16.x"
},
"custom": {
"modupdater": {
"strategy": "curseforge",
"projectID": 368420
}
}
}

View File

@ -3,14 +3,19 @@
"package": "com.thebrokenrail.slightlyvanilla.mixin",
"compatibilityLevel": "JAVA_8",
"client": [
"MixinClientPlayNetworkHandler"
"MixinClientPlayerInteractionManager",
"MixinClientPlayNetworkHandler",
"ScreenHandlerAccessor"
],
"mixins": [
"MixinRespawnAnchorBlock",
"MixinPlayerEntity",
"MixinAbstractTraderEntity",
"MixinItem",
"MixinSpawnEggItem",
"MixinLootableContainerBlockEntity"
"MixinLootableContainerBlockEntity",
"MixinNetherPortalBlockAreaHelper",
"MixinPlayerEntity",
"MixinRespawnAnchorBlock",
"MixinServerPlayerEntity",
"MixinSpawnEggItem"
],
"injectors": {
"defaultRequire": 1