1.17: mixins are done
This commit is contained in:
parent
f83cf94337
commit
bc714cafb3
|
@ -50,7 +50,7 @@ dependencies {
|
||||||
implementation "org.spigotmc:spigot-api:$minecraftVersion-R0.1-SNAPSHOT@jar"
|
implementation "org.spigotmc:spigot-api:$minecraftVersion-R0.1-SNAPSHOT@jar"
|
||||||
implementation 'org.jetbrains:annotations:19.0.0'
|
implementation 'org.jetbrains:annotations:19.0.0'
|
||||||
|
|
||||||
implementation 'org.spongepowered:mixin:0.8.2'
|
implementation 'org.spongepowered:mixin:0.8.3'
|
||||||
annotationProcessor 'org.spongepowered:mixin:0.8.2:processor'
|
annotationProcessor 'org.spongepowered:mixin:0.8.2:processor'
|
||||||
|
|
||||||
implementation 'com.github.ArclightTeam:mixin-tools:1.0.0'
|
implementation 'com.github.ArclightTeam:mixin-tools:1.0.0'
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
package io.izzel.arclight.common.bridge.tileentity;
|
package io.izzel.arclight.common.bridge.tileentity;
|
||||||
|
|
||||||
import java.util.List;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.crafting.Recipe;
|
import net.minecraft.world.item.crafting.Recipe;
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
import java.util.List;
|
||||||
|
|
||||||
public interface AbstractFurnaceTileEntityBridge {
|
public interface AbstractFurnaceTileEntityBridge {
|
||||||
|
|
||||||
List<Recipe<?>> bridge$dropExp(Level world, Vec3 pos, Player entity, ItemStack itemStack, int amount);
|
List<Recipe<?>> bridge$dropExp(ServerPlayer entity, ItemStack itemStack, int amount);
|
||||||
|
|
||||||
|
int bridge$getBurnDuration(ItemStack stack);
|
||||||
|
|
||||||
|
boolean bridge$isLit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,4 +7,6 @@ public interface ChunkHolderBridge {
|
||||||
int bridge$getOldTicketLevel();
|
int bridge$getOldTicketLevel();
|
||||||
|
|
||||||
LevelChunk bridge$getFullChunk();
|
LevelChunk bridge$getFullChunk();
|
||||||
|
|
||||||
|
LevelChunk bridge$getFullChunkUnchecked();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package io.izzel.arclight.common.bridge.world.server;
|
package io.izzel.arclight.common.bridge.world.server;
|
||||||
|
|
||||||
import io.izzel.arclight.common.mod.util.ArclightCallbackExecutor;
|
import io.izzel.arclight.common.mod.util.ArclightCallbackExecutor;
|
||||||
import java.util.function.BooleanSupplier;
|
|
||||||
import net.minecraft.server.level.ChunkHolder;
|
import net.minecraft.server.level.ChunkHolder;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
|
|
||||||
public interface ChunkManagerBridge {
|
import java.util.function.BooleanSupplier;
|
||||||
|
|
||||||
|
public interface ChunkMapBridge {
|
||||||
|
|
||||||
void bridge$tick(BooleanSupplier hasMoreTime);
|
void bridge$tick(BooleanSupplier hasMoreTime);
|
||||||
|
|
|
@ -27,9 +27,4 @@ public interface ServerWorldBridge extends WorldBridge {
|
||||||
boolean bridge$addAllEntitiesSafely(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason);
|
boolean bridge$addAllEntitiesSafely(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason);
|
||||||
|
|
||||||
LevelStorageSource.LevelStorageAccess bridge$getConvertable();
|
LevelStorageSource.LevelStorageAccess bridge$getConvertable();
|
||||||
|
|
||||||
interface Hack {
|
|
||||||
|
|
||||||
BlockEntity getTileEntity(BlockPos blockPos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
package io.izzel.arclight.common.bridge.world.storage;
|
package io.izzel.arclight.common.bridge.world.storage;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
||||||
import org.bukkit.craftbukkit.v.map.CraftMapView;
|
import org.bukkit.craftbukkit.v.map.CraftMapView;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface MapDataBridge {
|
public interface MapDataBridge {
|
||||||
|
|
||||||
CraftMapView bridge$getMapView();
|
CraftMapView bridge$getMapView();
|
||||||
|
|
||||||
|
void bridge$setId(String id);
|
||||||
|
|
||||||
|
List<MapItemSavedData.HoldingPlayer> bridge$getCarriedBy();
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,11 +60,10 @@ public abstract class CraftItemStackMixin implements CraftItemStackBridge {
|
||||||
if (stack == (Object) this) {
|
if (stack == (Object) this) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!(stack instanceof CraftItemStack)) {
|
if (!(stack instanceof CraftItemStack that)) {
|
||||||
return stack.getClass() == org.bukkit.inventory.ItemStack.class && stack.isSimilar((org.bukkit.inventory.ItemStack) (Object) this);
|
return stack.getClass() == org.bukkit.inventory.ItemStack.class && stack.isSimilar((org.bukkit.inventory.ItemStack) (Object) this);
|
||||||
}
|
}
|
||||||
|
|
||||||
CraftItemStack that = (CraftItemStack) stack;
|
|
||||||
if (handle == ((CraftItemStackBridge) (Object) that).bridge$getHandle()) {
|
if (handle == ((CraftItemStackBridge) (Object) that).bridge$getHandle()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import com.mojang.brigadier.StringReader;
|
||||||
import io.izzel.arclight.common.bridge.bukkit.CraftServerBridge;
|
import io.izzel.arclight.common.bridge.bukkit.CraftServerBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||||
import io.izzel.arclight.common.mod.server.ArclightServer;
|
import io.izzel.arclight.common.mod.server.ArclightServer;
|
||||||
import jline.console.ConsoleReader;
|
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
import net.minecraft.server.dedicated.DedicatedPlayerList;
|
import net.minecraft.server.dedicated.DedicatedPlayerList;
|
||||||
import net.minecraft.server.dedicated.DedicatedServer;
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
|
@ -37,7 +36,6 @@ import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -72,19 +70,6 @@ public abstract class CraftServerMixin implements CraftServerBridge {
|
||||||
return "Arclight";
|
return "Arclight";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @author IzzelAliz
|
|
||||||
* @reason
|
|
||||||
*/
|
|
||||||
@Overwrite(remap = false)
|
|
||||||
public ConsoleReader getReader() {
|
|
||||||
try {
|
|
||||||
return new ConsoleReader();
|
|
||||||
} catch (IOException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bridge$setPlayerList(PlayerList playerList) {
|
public void bridge$setPlayerList(PlayerList playerList) {
|
||||||
this.playerList = (DedicatedPlayerList) playerList;
|
this.playerList = (DedicatedPlayerList) playerList;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
package io.izzel.arclight.common.mixin.core.util.text;
|
package io.izzel.arclight.common.mixin.core.network.chat;
|
||||||
|
|
||||||
import com.google.common.collect.Streams;
|
import com.google.common.collect.Streams;
|
||||||
import io.izzel.arclight.common.bridge.util.text.ITextComponentBridge;
|
import io.izzel.arclight.common.bridge.util.text.ITextComponentBridge;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
@ -10,10 +11,9 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
|
|
||||||
@Mixin(Component.class)
|
@Mixin(Component.class)
|
||||||
public interface ITextComponentMixin extends ITextComponentBridge, Iterable<Component> {
|
public interface ComponentMixin extends ITextComponentBridge, Iterable<Component> {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow List<Component> getSiblings();
|
@Shadow List<Component> getSiblings();
|
|
@ -1,15 +1,15 @@
|
||||||
package io.izzel.arclight.common.mixin.core.util.text;
|
package io.izzel.arclight.common.mixin.core.network.chat;
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import net.minecraft.network.chat.ClickEvent;
|
import net.minecraft.network.chat.ClickEvent;
|
||||||
import net.minecraft.network.chat.HoverEvent;
|
import net.minecraft.network.chat.HoverEvent;
|
||||||
import net.minecraft.network.chat.Style;
|
import net.minecraft.network.chat.Style;
|
||||||
import net.minecraft.network.chat.TextColor;
|
import net.minecraft.network.chat.TextColor;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
@Mixin(Style.class)
|
@Mixin(Style.class)
|
||||||
public class StyleMixin {
|
public class StyleMixin {
|
|
@ -1,5 +1,7 @@
|
||||||
package io.izzel.arclight.common.mixin.core.util.text;
|
package io.izzel.arclight.common.mixin.core.network.chat;
|
||||||
|
|
||||||
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.network.chat.TextColor;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Mutable;
|
import org.spongepowered.asm.mixin.Mutable;
|
||||||
|
@ -9,11 +11,9 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import net.minecraft.ChatFormatting;
|
|
||||||
import net.minecraft.network.chat.TextColor;
|
|
||||||
|
|
||||||
@Mixin(TextColor.class)
|
@Mixin(TextColor.class)
|
||||||
public class ColorMixin {
|
public class TextColorMixin {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow @Final @Mutable @Nullable public String name;
|
@Shadow @Final @Mutable @Nullable public String name;
|
|
@ -1,6 +1,9 @@
|
||||||
package io.izzel.arclight.common.mixin.core.network.protocol.game;
|
package io.izzel.arclight.common.mixin.core.network.protocol.game;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
|
import net.minecraft.network.protocol.game.ServerGamePacketListener;
|
||||||
|
import net.minecraft.network.protocol.game.ServerboundChatPacket;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
@ -9,13 +12,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import net.minecraft.network.protocol.game.ServerGamePacketListener;
|
|
||||||
import net.minecraft.network.protocol.game.ServerboundChatPacket;
|
|
||||||
|
|
||||||
@Mixin(ServerboundChatPacket.class)
|
@Mixin(ServerboundChatPacket.class)
|
||||||
public class CChatMessagePacketMixin {
|
public class CChatMessagePacketMixin {
|
||||||
|
|
||||||
@Shadow private String message;
|
@Shadow @Final private String message;
|
||||||
|
|
||||||
private static final ExecutorService executors = Executors.newCachedThreadPool(
|
private static final ExecutorService executors = Executors.newCachedThreadPool(
|
||||||
new ThreadFactoryBuilder().setDaemon(true).setNameFormat("Async Chat Thread - #%d").build()
|
new ThreadFactoryBuilder().setDaemon(true).setNameFormat("Async Chat Thread - #%d").build()
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
package io.izzel.arclight.common.mixin.core.network.protocol.game;
|
package io.izzel.arclight.common.mixin.core.network.protocol.game;
|
||||||
|
|
||||||
import net.minecraft.network.protocol.game.ServerboundContainerClosePacket;
|
import net.minecraft.network.protocol.game.ServerboundContainerClosePacket;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Mutable;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
@Mixin(ServerboundContainerClosePacket.class)
|
@Mixin(ServerboundContainerClosePacket.class)
|
||||||
public class CCloseWindowPacketMixin {
|
public class CCloseWindowPacketMixin {
|
||||||
|
|
||||||
@Shadow private int containerId;
|
@Shadow @Final @Mutable private int containerId;
|
||||||
|
|
||||||
public void arclight$constructor() {
|
public void arclight$constructor() {
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
package io.izzel.arclight.common.mixin.core.util;
|
package io.izzel.arclight.common.mixin.core.server;
|
||||||
|
|
||||||
|
import io.izzel.arclight.api.Unsafe;
|
||||||
|
import net.minecraft.server.Bootstrap;
|
||||||
import org.bukkit.craftbukkit.v.util.CraftLegacy;
|
import org.bukkit.craftbukkit.v.util.CraftLegacy;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
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 io.izzel.arclight.api.Unsafe;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import net.minecraft.server.Bootstrap;
|
|
||||||
|
|
||||||
@Mixin(Bootstrap.class)
|
@Mixin(Bootstrap.class)
|
||||||
public class BootstrapMixin {
|
public class BootstrapMixin {
|
|
@ -1,10 +1,18 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.server;
|
package io.izzel.arclight.common.mixin.core.server.level;
|
||||||
|
|
||||||
import com.mojang.datafixers.util.Either;
|
import com.mojang.datafixers.util.Either;
|
||||||
import io.izzel.arclight.common.bridge.world.chunk.ChunkBridge;
|
import io.izzel.arclight.common.bridge.world.chunk.ChunkBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.server.ChunkHolderBridge;
|
import io.izzel.arclight.common.bridge.world.server.ChunkHolderBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.server.ChunkManagerBridge;
|
import io.izzel.arclight.common.bridge.world.server.ChunkMapBridge;
|
||||||
import io.izzel.arclight.common.mod.ArclightMod;
|
import io.izzel.arclight.common.mod.ArclightMod;
|
||||||
|
import it.unimi.dsi.fastutil.shorts.ShortSet;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.server.level.ChunkHolder;
|
||||||
|
import net.minecraft.server.level.ChunkMap;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
@ -16,12 +24,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import net.minecraft.server.level.ChunkHolder;
|
import java.util.concurrent.Executor;
|
||||||
import net.minecraft.server.level.ChunkMap;
|
|
||||||
import net.minecraft.world.level.ChunkPos;
|
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
|
||||||
|
|
||||||
@Mixin(ChunkHolder.class)
|
@Mixin(ChunkHolder.class)
|
||||||
public abstract class ChunkHolderMixin implements ChunkHolderBridge {
|
public abstract class ChunkHolderMixin implements ChunkHolderBridge {
|
||||||
|
@ -29,7 +32,8 @@ public abstract class ChunkHolderMixin implements ChunkHolderBridge {
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow public int oldTicketLevel;
|
@Shadow public int oldTicketLevel;
|
||||||
@Shadow public abstract CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> getFutureIfPresentUnchecked(ChunkStatus p_219301_1_);
|
@Shadow public abstract CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> getFutureIfPresentUnchecked(ChunkStatus p_219301_1_);
|
||||||
@Shadow @Final private ChunkPos pos;
|
@Shadow @Final ChunkPos pos;
|
||||||
|
@Shadow @Final private ShortSet[] changedBlocksPerSection;
|
||||||
@Override @Accessor("oldTicketLevel") public abstract int bridge$getOldTicketLevel();
|
@Override @Accessor("oldTicketLevel") public abstract int bridge$getOldTicketLevel();
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
|
@ -37,9 +41,13 @@ public abstract class ChunkHolderMixin implements ChunkHolderBridge {
|
||||||
if (!ChunkHolder.getFullChunkStatus(this.oldTicketLevel).isOrAfter(ChunkHolder.FullChunkStatus.BORDER)) {
|
if (!ChunkHolder.getFullChunkStatus(this.oldTicketLevel).isOrAfter(ChunkHolder.FullChunkStatus.BORDER)) {
|
||||||
return null; // note: using oldTicketLevel for isLoaded checks
|
return null; // note: using oldTicketLevel for isLoaded checks
|
||||||
}
|
}
|
||||||
|
return this.getFullChunkUnchecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LevelChunk getFullChunkUnchecked() {
|
||||||
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> statusFuture = this.getFutureIfPresentUnchecked(ChunkStatus.FULL);
|
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> statusFuture = this.getFutureIfPresentUnchecked(ChunkStatus.FULL);
|
||||||
Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> either = statusFuture.getNow(null);
|
Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> either = statusFuture.getNow(null);
|
||||||
return either == null ? null : (LevelChunk) either.left().orElse(null);
|
return (either == null) ? null : (LevelChunk) either.left().orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -47,16 +55,27 @@ public abstract class ChunkHolderMixin implements ChunkHolderBridge {
|
||||||
return this.getFullChunk();
|
return this.getFullChunk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LevelChunk bridge$getFullChunkUnchecked() {
|
||||||
|
return this.getFullChunkUnchecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "blockChanged", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,
|
||||||
|
at = @At(value = "FIELD", ordinal = 0, target = "Lnet/minecraft/server/level/ChunkHolder;changedBlocksPerSection:[Lit/unimi/dsi/fastutil/shorts/ShortSet;"))
|
||||||
|
private void arclight$outOfBound(BlockPos pos, CallbackInfo ci, int i) {
|
||||||
|
if (i < 0 || i >= this.changedBlocksPerSection.length) return;
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(method = "updateFutures", at = @At(value = "JUMP", opcode = Opcodes.IFEQ, ordinal = 0),
|
@Inject(method = "updateFutures", at = @At(value = "JUMP", opcode = Opcodes.IFEQ, ordinal = 0),
|
||||||
locals = LocalCapture.CAPTURE_FAILHARD)
|
locals = LocalCapture.CAPTURE_FAILHARD)
|
||||||
public void arclight$onChunkUnload(ChunkMap chunkManager, CallbackInfo ci, ChunkStatus chunkStatus,
|
public void arclight$onChunkUnload(ChunkMap chunkManager, Executor executor, CallbackInfo ci, ChunkStatus chunkStatus,
|
||||||
ChunkStatus chunkStatus1, boolean flag, boolean flag1,
|
ChunkStatus chunkStatus1, boolean flag, boolean flag1,
|
||||||
ChunkHolder.FullChunkStatus locationType, ChunkHolder.FullChunkStatus locationType1) {
|
ChunkHolder.FullChunkStatus locationType, ChunkHolder.FullChunkStatus locationType1) {
|
||||||
if (locationType.isOrAfter(ChunkHolder.FullChunkStatus.BORDER) && !locationType1.isOrAfter(ChunkHolder.FullChunkStatus.BORDER)) {
|
if (locationType.isOrAfter(ChunkHolder.FullChunkStatus.BORDER) && !locationType1.isOrAfter(ChunkHolder.FullChunkStatus.BORDER)) {
|
||||||
this.getFutureIfPresentUnchecked(ChunkStatus.FULL).thenAccept((either) -> {
|
this.getFutureIfPresentUnchecked(ChunkStatus.FULL).thenAccept((either) -> {
|
||||||
LevelChunk chunk = (LevelChunk) either.left().orElse(null);
|
LevelChunk chunk = (LevelChunk) either.left().orElse(null);
|
||||||
if (chunk != null) {
|
if (chunk != null) {
|
||||||
((ChunkManagerBridge) chunkManager).bridge$getCallbackExecutor().execute(() -> {
|
((ChunkMapBridge) chunkManager).bridge$getCallbackExecutor().execute(() -> {
|
||||||
chunk.setUnsaved(true);
|
chunk.setUnsaved(true);
|
||||||
((ChunkBridge) chunk).bridge$unloadCallback();
|
((ChunkBridge) chunk).bridge$unloadCallback();
|
||||||
});
|
});
|
||||||
|
@ -68,19 +87,19 @@ public abstract class ChunkHolderMixin implements ChunkHolderBridge {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Run callback right away if the future was already done
|
// Run callback right away if the future was already done
|
||||||
((ChunkManagerBridge) chunkManager).bridge$getCallbackExecutor().run();
|
((ChunkMapBridge) chunkManager).bridge$getCallbackExecutor().run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "updateFutures", at = @At("RETURN"), locals = LocalCapture.CAPTURE_FAILHARD)
|
@Inject(method = "updateFutures", at = @At("RETURN"), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||||
public void arclight$onChunkLoad(ChunkMap chunkManager, CallbackInfo ci, ChunkStatus chunkStatus,
|
public void arclight$onChunkLoad(ChunkMap chunkManager, Executor executor, CallbackInfo ci, ChunkStatus chunkStatus,
|
||||||
ChunkStatus chunkStatus1, boolean flag, boolean flag1,
|
ChunkStatus chunkStatus1, boolean flag, boolean flag1,
|
||||||
ChunkHolder.FullChunkStatus locationType, ChunkHolder.FullChunkStatus locationType1) {
|
ChunkHolder.FullChunkStatus locationType, ChunkHolder.FullChunkStatus locationType1) {
|
||||||
if (!locationType.isOrAfter(ChunkHolder.FullChunkStatus.BORDER) && locationType1.isOrAfter(ChunkHolder.FullChunkStatus.BORDER)) {
|
if (!locationType.isOrAfter(ChunkHolder.FullChunkStatus.BORDER) && locationType1.isOrAfter(ChunkHolder.FullChunkStatus.BORDER)) {
|
||||||
this.getFutureIfPresentUnchecked(ChunkStatus.FULL).thenAccept((either) -> {
|
this.getFutureIfPresentUnchecked(ChunkStatus.FULL).thenAccept((either) -> {
|
||||||
LevelChunk chunk = (LevelChunk) either.left().orElse(null);
|
LevelChunk chunk = (LevelChunk) either.left().orElse(null);
|
||||||
if (chunk != null) {
|
if (chunk != null) {
|
||||||
((ChunkManagerBridge) chunkManager).bridge$getCallbackExecutor().execute(
|
((ChunkMapBridge) chunkManager).bridge$getCallbackExecutor().execute(
|
||||||
((ChunkBridge) chunk)::bridge$loadCallback
|
((ChunkBridge) chunk)::bridge$loadCallback
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -90,7 +109,7 @@ public abstract class ChunkHolderMixin implements ChunkHolderBridge {
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
((ChunkManagerBridge) chunkManager).bridge$getCallbackExecutor().run();
|
((ChunkMapBridge) chunkManager).bridge$getCallbackExecutor().run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,8 +1,15 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.server;
|
package io.izzel.arclight.common.mixin.core.server.level;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.server.ChunkManagerBridge;
|
import io.izzel.arclight.common.bridge.world.server.ChunkMapBridge;
|
||||||
import io.izzel.arclight.common.mod.util.ArclightCallbackExecutor;
|
import io.izzel.arclight.common.mod.util.ArclightCallbackExecutor;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.server.level.ChunkHolder;
|
||||||
|
import net.minecraft.server.level.ChunkMap;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
|
import net.minecraft.world.level.dimension.DimensionType;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Mutable;
|
import org.spongepowered.asm.mixin.Mutable;
|
||||||
|
@ -12,17 +19,10 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import net.minecraft.resources.ResourceKey;
|
|
||||||
import net.minecraft.server.level.ChunkHolder;
|
|
||||||
import net.minecraft.server.level.ChunkMap;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.world.level.ChunkPos;
|
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
|
||||||
import net.minecraft.world.level.dimension.DimensionType;
|
|
||||||
import java.util.function.BooleanSupplier;
|
import java.util.function.BooleanSupplier;
|
||||||
|
|
||||||
@Mixin(ChunkMap.class)
|
@Mixin(ChunkMap.class)
|
||||||
public abstract class ChunkManagerMixin implements ChunkManagerBridge {
|
public abstract class ChunkMapMixin implements ChunkMapBridge {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow @Nullable protected abstract ChunkHolder getUpdatingChunkIfPresent(long chunkPosIn);
|
@Shadow @Nullable protected abstract ChunkHolder getUpdatingChunkIfPresent(long chunkPosIn);
|
|
@ -1,6 +1,10 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.server;
|
package io.izzel.arclight.common.mixin.core.server.level;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.world.TrackedEntityBridge;
|
import io.izzel.arclight.common.bridge.world.TrackedEntityBridge;
|
||||||
|
import net.minecraft.server.level.ChunkMap;
|
||||||
|
import net.minecraft.server.level.ServerEntity;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
@ -9,16 +13,12 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import net.minecraft.server.level.ChunkMap;
|
|
||||||
import net.minecraft.server.level.ServerEntity;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
|
|
||||||
@Mixin(ChunkMap.TrackedEntity.class)
|
@Mixin(ChunkMap.TrackedEntity.class)
|
||||||
public abstract class ChunkManager_EntityTrackerMixin {
|
public abstract class ChunkMap_TrackedEntityMixin {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow @Final private ServerEntity serverEntity;
|
@Shadow @Final ServerEntity serverEntity;
|
||||||
@Shadow @Final public Set<ServerPlayer> seenBy;
|
@Shadow @Final public Set<ServerPlayer> seenBy;
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
|
@ -1,21 +1,10 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.server;
|
package io.izzel.arclight.common.mixin.core.server.level;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.server.ChunkHolderBridge;
|
import io.izzel.arclight.common.bridge.world.server.ChunkHolderBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.server.ChunkManagerBridge;
|
import io.izzel.arclight.common.bridge.world.server.ChunkMapBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.server.ServerChunkProviderBridge;
|
import io.izzel.arclight.common.bridge.world.server.ServerChunkProviderBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.server.TicketManagerBridge;
|
import io.izzel.arclight.common.bridge.world.server.TicketManagerBridge;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Mutable;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
|
||||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import net.minecraft.server.level.ChunkHolder;
|
import net.minecraft.server.level.ChunkHolder;
|
||||||
import net.minecraft.server.level.ChunkMap;
|
import net.minecraft.server.level.ChunkMap;
|
||||||
import net.minecraft.server.level.DistanceManager;
|
import net.minecraft.server.level.DistanceManager;
|
||||||
|
@ -27,21 +16,32 @@ import net.minecraft.world.level.GameRules;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraft.world.level.storage.LevelData;
|
import net.minecraft.world.level.storage.LevelData;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Mutable;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@Mixin(ServerChunkCache.class)
|
@Mixin(ServerChunkCache.class)
|
||||||
public abstract class ServerChunkProviderMixin implements ServerChunkProviderBridge {
|
public abstract class ServerChunkCacheMixin implements ServerChunkProviderBridge {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow public abstract void save(boolean flush);
|
@Shadow public abstract void save(boolean flush);
|
||||||
@Shadow @Final private ThreadedLevelLightEngine lightEngine;
|
@Shadow @Final ThreadedLevelLightEngine lightEngine;
|
||||||
@Shadow @Final public ChunkMap chunkMap;
|
@Shadow @Final public ChunkMap chunkMap;
|
||||||
@Shadow @Final public ServerLevel level;
|
@Shadow @Final public ServerLevel level;
|
||||||
@Shadow @Final private DistanceManager distanceManager;
|
@Shadow @Final private DistanceManager distanceManager;
|
||||||
@Shadow protected abstract void clearCache();
|
@Shadow protected abstract void clearCache();
|
||||||
@Shadow @Nullable protected abstract ChunkHolder getVisibleChunkIfPresent(long chunkPosIn);
|
@Shadow @Nullable protected abstract ChunkHolder getVisibleChunkIfPresent(long chunkPosIn);
|
||||||
@Shadow protected abstract boolean runDistanceManagerUpdates();
|
@Shadow abstract boolean runDistanceManagerUpdates();
|
||||||
@Shadow protected abstract boolean chunkAbsent(@Nullable ChunkHolder chunkHolderIn, int p_217224_2_);
|
@Shadow protected abstract boolean chunkAbsent(@Nullable ChunkHolder chunkHolderIn, int p_217224_2_);
|
||||||
@Shadow public boolean spawnEnemies;
|
@Shadow public boolean spawnEnemies;
|
||||||
@Shadow public boolean spawnFriendlies;
|
@Shadow public boolean spawnFriendlies;
|
||||||
|
@ -52,10 +52,18 @@ public abstract class ServerChunkProviderMixin implements ServerChunkProviderBri
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
public boolean isChunkLoaded(final int chunkX, final int chunkZ) {
|
public boolean isChunkLoaded(final int chunkX, final int chunkZ) {
|
||||||
final ChunkHolder chunk = ((ChunkManagerBridge) this.chunkMap).bridge$chunkHolderAt(ChunkPos.asLong(chunkX, chunkZ));
|
ChunkHolder chunk = ((ChunkMapBridge) this.chunkMap).bridge$chunkHolderAt(ChunkPos.asLong(chunkX, chunkZ));
|
||||||
return chunk != null && ((ChunkHolderBridge) chunk).bridge$getFullChunk() != null;
|
return chunk != null && ((ChunkHolderBridge) chunk).bridge$getFullChunk() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LevelChunk getChunkUnchecked(int chunkX, int chunkZ) {
|
||||||
|
ChunkHolder chunk = ((ChunkMapBridge) this.chunkMap).bridge$chunkHolderAt(ChunkPos.asLong(chunkX, chunkZ));
|
||||||
|
if (chunk == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return ((ChunkHolderBridge) chunk).bridge$getFullChunkUnchecked();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean bridge$isChunkLoaded(int x, int z) {
|
public boolean bridge$isChunkLoaded(int x, int z) {
|
||||||
return isChunkLoaded(x, z);
|
return isChunkLoaded(x, z);
|
||||||
|
@ -64,12 +72,12 @@ public abstract class ServerChunkProviderMixin implements ServerChunkProviderBri
|
||||||
@Override
|
@Override
|
||||||
public void bridge$setChunkGenerator(ChunkGenerator chunkGenerator) {
|
public void bridge$setChunkGenerator(ChunkGenerator chunkGenerator) {
|
||||||
this.generator = chunkGenerator;
|
this.generator = chunkGenerator;
|
||||||
((ChunkManagerBridge) this.chunkMap).bridge$setChunkGenerator(chunkGenerator);
|
((ChunkMapBridge) this.chunkMap).bridge$setChunkGenerator(chunkGenerator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bridge$setViewDistance(int viewDistance) {
|
public void bridge$setViewDistance(int viewDistance) {
|
||||||
((ChunkManagerBridge) this.chunkMap).bridge$setViewDistance(viewDistance);
|
((ChunkMapBridge) this.chunkMap).bridge$setViewDistance(viewDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ModifyVariable(method = "getChunkFutureMainThread", index = 4, at = @At("HEAD"))
|
@ModifyVariable(method = "getChunkFutureMainThread", index = 4, at = @At("HEAD"))
|
||||||
|
@ -113,7 +121,7 @@ public abstract class ServerChunkProviderMixin implements ServerChunkProviderBri
|
||||||
((TicketManagerBridge) this.distanceManager).bridge$tick();
|
((TicketManagerBridge) this.distanceManager).bridge$tick();
|
||||||
this.bridge$tickDistanceManager();
|
this.bridge$tickDistanceManager();
|
||||||
this.level.getProfiler().popPush("unload");
|
this.level.getProfiler().popPush("unload");
|
||||||
((ChunkManagerBridge) this.chunkMap).bridge$tick(() -> true);
|
((ChunkMapBridge) this.chunkMap).bridge$tick(() -> true);
|
||||||
this.level.getProfiler().pop();
|
this.level.getProfiler().pop();
|
||||||
this.clearCache();
|
this.clearCache();
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.server;
|
package io.izzel.arclight.common.mixin.core.server.level;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.server.MinecraftServerBridge;
|
import io.izzel.arclight.common.bridge.server.MinecraftServerBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.server.ChunkManagerBridge;
|
import io.izzel.arclight.common.bridge.world.server.ChunkMapBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.server.ServerChunkProviderBridge;
|
import io.izzel.arclight.common.bridge.world.server.ServerChunkProviderBridge;
|
||||||
import io.izzel.arclight.common.mod.server.ArclightServer;
|
import io.izzel.arclight.common.mod.server.ArclightServer;
|
||||||
import net.minecraft.server.level.ServerChunkCache;
|
import net.minecraft.server.level.ServerChunkCache;
|
||||||
|
@ -12,13 +12,13 @@ import org.spongepowered.asm.mixin.Overwrite;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
@Mixin(targets = "net.minecraft.server.level.ServerChunkCache$MainThreadExecutor")
|
@Mixin(targets = "net.minecraft.server.level.ServerChunkCache$MainThreadExecutor")
|
||||||
public abstract class ServerChunkProvider_ChunkExecutorMixin extends BlockableEventLoop<Runnable> {
|
public abstract class ServerChunkCache_MainThreadExecutorMixin extends BlockableEventLoop<Runnable> {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow(aliases = {"this$0", "field_213181_a"}, remap = false) @Final private ServerChunkCache outer;
|
@Shadow(aliases = {"this$0", "f_8491_"}, remap = false) @Final private ServerChunkCache outer;
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
protected ServerChunkProvider_ChunkExecutorMixin(String nameIn) {
|
protected ServerChunkCache_MainThreadExecutorMixin(String nameIn) {
|
||||||
super(nameIn);
|
super(nameIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ public abstract class ServerChunkProvider_ChunkExecutorMixin extends BlockableEv
|
||||||
* @reason
|
* @reason
|
||||||
*/
|
*/
|
||||||
@Overwrite
|
@Overwrite
|
||||||
protected boolean pollTask() {
|
public boolean pollTask() {
|
||||||
try {
|
try {
|
||||||
if (((ServerChunkProviderBridge) outer).bridge$tickDistanceManager()) {
|
if (((ServerChunkProviderBridge) outer).bridge$tickDistanceManager()) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -36,7 +36,7 @@ public abstract class ServerChunkProvider_ChunkExecutorMixin extends BlockableEv
|
||||||
return super.pollTask();
|
return super.pollTask();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
((ChunkManagerBridge) outer.chunkMap).bridge$getCallbackExecutor().run();
|
((ChunkMapBridge) outer.chunkMap).bridge$getCallbackExecutor().run();
|
||||||
((MinecraftServerBridge) ArclightServer.getMinecraftServer()).bridge$drainQueuedTasks();
|
((MinecraftServerBridge) ArclightServer.getMinecraftServer()).bridge$drainQueuedTasks();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,28 +1,9 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world;
|
package io.izzel.arclight.common.mixin.core.server.level;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.TrackedEntityBridge;
|
import io.izzel.arclight.common.bridge.world.TrackedEntityBridge;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.player.PlayerVelocityEvent;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
|
||||||
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;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import net.minecraft.network.protocol.Packet;
|
import net.minecraft.network.protocol.Packet;
|
||||||
import net.minecraft.network.protocol.game.ClientboundAddMobPacket;
|
import net.minecraft.network.protocol.game.ClientboundAddMobPacket;
|
||||||
import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket;
|
import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket;
|
||||||
|
@ -52,9 +33,28 @@ import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.MapItem;
|
import net.minecraft.world.item.MapItem;
|
||||||
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.player.PlayerVelocityEvent;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
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;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@Mixin(ServerEntity.class)
|
@Mixin(ServerEntity.class)
|
||||||
public abstract class TrackedEntityMixin implements TrackedEntityBridge {
|
public abstract class ServerEntityMixin implements TrackedEntityBridge {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow @Final private Entity entity;
|
@Shadow @Final private Entity entity;
|
||||||
|
@ -111,16 +111,17 @@ public abstract class TrackedEntityMixin implements TrackedEntityBridge {
|
||||||
this.lastPassengers = list;
|
this.lastPassengers = list;
|
||||||
this.broadcastAndSend(new ClientboundSetPassengersPacket(this.entity));
|
this.broadcastAndSend(new ClientboundSetPassengersPacket(this.entity));
|
||||||
}
|
}
|
||||||
if (this.entity instanceof ItemFrame) {
|
if (this.entity instanceof ItemFrame itemFrame) {
|
||||||
ItemFrame itemframeentity = (ItemFrame) this.entity;
|
ItemStack itemstack = itemFrame.getItem();
|
||||||
ItemStack itemstack = itemframeentity.getItem();
|
if (this.tickCount % 10 == 0 && itemstack.getItem() instanceof MapItem) {
|
||||||
MapItemSavedData mapdata = MapItem.getOrCreateSavedData(itemstack, this.level);
|
MapItemSavedData mapdata = MapItem.getSavedData(itemstack, this.level);
|
||||||
if (this.tickCount % 10 == 0 && mapdata != null && itemstack.getItem() instanceof MapItem) {
|
if (mapdata != null) {
|
||||||
for (ServerPlayer serverplayerentity : this.trackedPlayers) {
|
for (ServerPlayer serverplayerentity : this.trackedPlayers) {
|
||||||
mapdata.tickCarriedBy(serverplayerentity, itemstack);
|
mapdata.tickCarriedBy(serverplayerentity, itemstack);
|
||||||
Packet<?> ipacket = ((MapItem) itemstack.getItem()).getUpdatePacket(itemstack, this.level, serverplayerentity);
|
Packet<?> ipacket = ((MapItem) itemstack.getItem()).getUpdatePacket(itemstack, this.level, serverplayerentity);
|
||||||
if (ipacket != null) {
|
if (ipacket != null) {
|
||||||
serverplayerentity.connection.send(ipacket);
|
serverplayerentity.connection.send(ipacket);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,8 +129,8 @@ public abstract class TrackedEntityMixin implements TrackedEntityBridge {
|
||||||
}
|
}
|
||||||
if (this.tickCount % this.updateInterval == 0 || this.entity.hasImpulse || this.entity.getEntityData().isDirty()) {
|
if (this.tickCount % this.updateInterval == 0 || this.entity.hasImpulse || this.entity.getEntityData().isDirty()) {
|
||||||
if (this.entity.isPassenger()) {
|
if (this.entity.isPassenger()) {
|
||||||
int i1 = Mth.floor(this.entity.yRot * 256.0F / 360.0F);
|
int i1 = Mth.floor(this.entity.getYRot() * 256.0F / 360.0F);
|
||||||
int l1 = Mth.floor(this.entity.xRot * 256.0F / 360.0F);
|
int l1 = Mth.floor(this.entity.getXRot() * 256.0F / 360.0F);
|
||||||
boolean flag2 = Math.abs(i1 - this.yRotp) >= 1 || Math.abs(l1 - this.xRotp) >= 1;
|
boolean flag2 = Math.abs(i1 - this.yRotp) >= 1 || Math.abs(l1 - this.xRotp) >= 1;
|
||||||
if (flag2) {
|
if (flag2) {
|
||||||
this.broadcast.accept(new ClientboundMoveEntityPacket.Rot(this.entity.getId(), (byte) i1, (byte) l1, this.entity.isOnGround()));
|
this.broadcast.accept(new ClientboundMoveEntityPacket.Rot(this.entity.getId(), (byte) i1, (byte) l1, this.entity.isOnGround()));
|
||||||
|
@ -141,8 +142,8 @@ public abstract class TrackedEntityMixin implements TrackedEntityBridge {
|
||||||
this.wasRiding = true;
|
this.wasRiding = true;
|
||||||
} else {
|
} else {
|
||||||
++this.teleportDelay;
|
++this.teleportDelay;
|
||||||
int l = Mth.floor(this.entity.yRot * 256.0F / 360.0F);
|
int l = Mth.floor(this.entity.getYRot() * 256.0F / 360.0F);
|
||||||
int k1 = Mth.floor(this.entity.xRot * 256.0F / 360.0F);
|
int k1 = Mth.floor(this.entity.getXRot() * 256.0F / 360.0F);
|
||||||
Vec3 vector3d = this.entity.position().subtract(ClientboundMoveEntityPacket.packetToEntity(this.xp, this.yp, this.zp));
|
Vec3 vector3d = this.entity.position().subtract(ClientboundMoveEntityPacket.packetToEntity(this.xp, this.yp, this.zp));
|
||||||
boolean flag3 = vector3d.lengthSqr() >= (double) 7.6293945E-6F;
|
boolean flag3 = vector3d.lengthSqr() >= (double) 7.6293945E-6F;
|
||||||
Packet<?> ipacket1 = null;
|
Packet<?> ipacket1 = null;
|
||||||
|
@ -239,7 +240,7 @@ public abstract class TrackedEntityMixin implements TrackedEntityBridge {
|
||||||
ServerPlayer player = arclight$player;
|
ServerPlayer player = arclight$player;
|
||||||
arclight$player = null;
|
arclight$player = null;
|
||||||
Mob entityinsentient;
|
Mob entityinsentient;
|
||||||
if (this.entity.removed) {
|
if (this.entity.isRemoved()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Packet<?> packet = this.entity.getAddEntityPacket();
|
Packet<?> packet = this.entity.getAddEntityPacket();
|
||||||
|
@ -249,15 +250,15 @@ public abstract class TrackedEntityMixin implements TrackedEntityBridge {
|
||||||
consumer.accept(new ClientboundSetEntityDataPacket(this.entity.getId(), this.entity.getEntityData(), true));
|
consumer.accept(new ClientboundSetEntityDataPacket(this.entity.getId(), this.entity.getEntityData(), true));
|
||||||
}
|
}
|
||||||
boolean flag = this.trackDelta;
|
boolean flag = this.trackDelta;
|
||||||
if (this.entity instanceof LivingEntity) {
|
if (this.entity instanceof LivingEntity livingEntity) {
|
||||||
Collection<AttributeInstance> collection = ((LivingEntity) this.entity).getAttributes().getSyncableAttributes();
|
Collection<AttributeInstance> collection = livingEntity.getAttributes().getSyncableAttributes();
|
||||||
if (this.entity.getId() == player.getId()) {
|
if (this.entity.getId() == player.getId()) {
|
||||||
((ServerPlayerEntityBridge) this.entity).bridge$getBukkitEntity().injectScaledMaxHealth(collection, false);
|
((ServerPlayerEntityBridge) this.entity).bridge$getBukkitEntity().injectScaledMaxHealth(collection, false);
|
||||||
}
|
}
|
||||||
if (!collection.isEmpty()) {
|
if (!collection.isEmpty()) {
|
||||||
consumer.accept(new ClientboundUpdateAttributesPacket(this.entity.getId(), collection));
|
consumer.accept(new ClientboundUpdateAttributesPacket(this.entity.getId(), collection));
|
||||||
}
|
}
|
||||||
if (((LivingEntity) this.entity).isFallFlying()) {
|
if (livingEntity.isFallFlying()) {
|
||||||
flag = true;
|
flag = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,11 +279,11 @@ public abstract class TrackedEntityMixin implements TrackedEntityBridge {
|
||||||
}
|
}
|
||||||
this.yHeadRotp = Mth.floor(this.entity.getYHeadRot() * 256.0f / 360.0f);
|
this.yHeadRotp = Mth.floor(this.entity.getYHeadRot() * 256.0f / 360.0f);
|
||||||
consumer.accept(new ClientboundRotateHeadPacket(this.entity, (byte) this.yHeadRotp));
|
consumer.accept(new ClientboundRotateHeadPacket(this.entity, (byte) this.yHeadRotp));
|
||||||
if (this.entity instanceof LivingEntity) {
|
if (this.entity instanceof LivingEntity livingEntity) {
|
||||||
LivingEntity entityliving = (LivingEntity) this.entity;
|
for (MobEffectInstance mobeffect : livingEntity.getActiveEffects()) {
|
||||||
for (MobEffectInstance mobeffect : entityliving.getActiveEffects()) {
|
|
||||||
consumer.accept(new ClientboundUpdateMobEffectPacket(this.entity.getId(), mobeffect));
|
consumer.accept(new ClientboundUpdateMobEffectPacket(this.entity.getId(), mobeffect));
|
||||||
}
|
}
|
||||||
|
livingEntity.detectEquipmentUpdates();
|
||||||
}
|
}
|
||||||
if (!this.entity.getPassengers().isEmpty()) {
|
if (!this.entity.getPassengers().isEmpty()) {
|
||||||
consumer.accept(new ClientboundSetPassengersPacket(this.entity));
|
consumer.accept(new ClientboundSetPassengersPacket(this.entity));
|
||||||
|
@ -297,8 +298,8 @@ public abstract class TrackedEntityMixin implements TrackedEntityBridge {
|
||||||
|
|
||||||
@Inject(method = "sendDirtyEntityData", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/server/level/ServerEntity;broadcastAndSend(Lnet/minecraft/network/protocol/Packet;)V"))
|
@Inject(method = "sendDirtyEntityData", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/server/level/ServerEntity;broadcastAndSend(Lnet/minecraft/network/protocol/Packet;)V"))
|
||||||
private void arclight$sendScaledHealth(CallbackInfo ci, SynchedEntityData entitydatamanager, Set<AttributeInstance> set) {
|
private void arclight$sendScaledHealth(CallbackInfo ci, SynchedEntityData entitydatamanager, Set<AttributeInstance> set) {
|
||||||
if (this.entity instanceof ServerPlayer) {
|
if (this.entity instanceof ServerPlayerEntityBridge player) {
|
||||||
((ServerPlayerEntityBridge) this.entity).bridge$getBukkitEntity().injectScaledMaxHealth(set, false);
|
player.bridge$getBukkitEntity().injectScaledMaxHealth(set, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.server;
|
package io.izzel.arclight.common.mixin.core.server.level;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
||||||
|
@ -11,18 +11,16 @@ import io.izzel.arclight.common.bridge.world.server.ServerWorldBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.storage.DerivedWorldInfoBridge;
|
import io.izzel.arclight.common.bridge.world.storage.DerivedWorldInfoBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.storage.MapDataBridge;
|
import io.izzel.arclight.common.bridge.world.storage.MapDataBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.storage.WorldInfoBridge;
|
import io.izzel.arclight.common.bridge.world.storage.WorldInfoBridge;
|
||||||
import io.izzel.arclight.common.mixin.core.world.WorldMixin;
|
import io.izzel.arclight.common.mixin.core.world.level.LevelMixin;
|
||||||
import io.izzel.arclight.common.mod.server.world.WorldSymlink;
|
import io.izzel.arclight.common.mod.server.world.WorldSymlink;
|
||||||
import io.izzel.arclight.common.mod.util.ArclightCaptures;
|
import io.izzel.arclight.common.mod.util.ArclightCaptures;
|
||||||
import io.izzel.arclight.common.mod.util.DelegateWorldInfo;
|
import io.izzel.arclight.common.mod.util.DelegateWorldInfo;
|
||||||
import io.izzel.arclight.i18n.ArclightConfig;
|
import io.izzel.arclight.i18n.ArclightConfig;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.particles.ParticleOptions;
|
import net.minecraft.core.particles.ParticleOptions;
|
||||||
import net.minecraft.network.protocol.Packet;
|
import net.minecraft.network.protocol.Packet;
|
||||||
import net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket;
|
import net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.level.ServerChunkCache;
|
import net.minecraft.server.level.ServerChunkCache;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
@ -33,8 +31,6 @@ import net.minecraft.world.Container;
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
import net.minecraft.world.damagesource.DamageSource;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.LightningBolt;
|
import net.minecraft.world.entity.LightningBolt;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
|
||||||
import net.minecraft.world.level.BlockGetter;
|
|
||||||
import net.minecraft.world.level.CustomSpawner;
|
import net.minecraft.world.level.CustomSpawner;
|
||||||
import net.minecraft.world.level.Explosion;
|
import net.minecraft.world.level.Explosion;
|
||||||
import net.minecraft.world.level.ExplosionDamageCalculator;
|
import net.minecraft.world.level.ExplosionDamageCalculator;
|
||||||
|
@ -45,6 +41,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraft.world.level.dimension.DimensionType;
|
import net.minecraft.world.level.dimension.DimensionType;
|
||||||
|
import net.minecraft.world.level.entity.PersistentEntitySectionManager;
|
||||||
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
||||||
import net.minecraft.world.level.storage.DerivedLevelData;
|
import net.minecraft.world.level.storage.DerivedLevelData;
|
||||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||||
|
@ -67,8 +64,6 @@ import org.bukkit.event.world.TimeSkipEvent;
|
||||||
import org.bukkit.event.world.WorldSaveEvent;
|
import org.bukkit.event.world.WorldSaveEvent;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Implements;
|
|
||||||
import org.spongepowered.asm.mixin.Interface;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
@ -84,11 +79,9 @@ import javax.annotation.Nullable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
@Mixin(ServerLevel.class)
|
@Mixin(ServerLevel.class)
|
||||||
@Implements(@Interface(iface = ServerWorldBridge.Hack.class, prefix = "hack$"))
|
public abstract class ServerLevelMixin extends LevelMixin implements ServerWorldBridge {
|
||||||
public abstract class ServerWorldMixin extends WorldMixin implements ServerWorldBridge {
|
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow public abstract boolean addFreshEntity(Entity entityIn);
|
@Shadow public abstract boolean addFreshEntity(Entity entityIn);
|
||||||
|
@ -97,18 +90,17 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld
|
||||||
@Shadow protected abstract boolean sendParticles(ServerPlayer player, boolean longDistance, double posX, double posY, double posZ, Packet<?> packet);
|
@Shadow protected abstract boolean sendParticles(ServerPlayer player, boolean longDistance, double posX, double posY, double posZ, Packet<?> packet);
|
||||||
@Shadow @Nonnull public abstract MinecraftServer shadow$getServer();
|
@Shadow @Nonnull public abstract MinecraftServer shadow$getServer();
|
||||||
@Shadow @Final private List<ServerPlayer> players;
|
@Shadow @Final private List<ServerPlayer> players;
|
||||||
@Shadow @Final public Int2ObjectMap<Entity> entitiesById;
|
|
||||||
@Shadow public abstract ServerChunkCache getChunkSource();
|
@Shadow public abstract ServerChunkCache getChunkSource();
|
||||||
@Shadow private boolean allPlayersSleeping;
|
|
||||||
@Shadow protected abstract void wakeUpAllPlayers();
|
@Shadow protected abstract void wakeUpAllPlayers();
|
||||||
@Shadow @Final private ServerChunkCache chunkSource;
|
@Shadow @Final private ServerChunkCache chunkSource;
|
||||||
@Shadow protected abstract boolean isUUIDUsed(Entity entityIn);
|
|
||||||
@Shadow @Final public static BlockPos END_SPAWN_POINT;
|
@Shadow @Final public static BlockPos END_SPAWN_POINT;
|
||||||
@Shadow @Final public ServerLevelData serverLevelData;
|
@Shadow @Final public ServerLevelData serverLevelData;
|
||||||
|
@Shadow @Final private PersistentEntitySectionManager<Entity> entityManager;
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
||||||
public PrimaryLevelData $$worldDataServer;
|
public PrimaryLevelData $$worldDataServer;
|
||||||
|
private int tickPosition;
|
||||||
public LevelStorageSource.LevelStorageAccess convertable;
|
public LevelStorageSource.LevelStorageAccess convertable;
|
||||||
public UUID uuid;
|
public UUID uuid;
|
||||||
|
|
||||||
|
@ -131,7 +123,7 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld
|
||||||
private void arclight$init(MinecraftServer minecraftServer, Executor backgroundExecutor, LevelStorageSource.LevelStorageAccess levelSave, ServerLevelData worldInfo, ResourceKey<net.minecraft.world.level.Level> dimension, DimensionType dimensionType, ChunkProgressListener statusListener, ChunkGenerator chunkGenerator, boolean isDebug, long seed, List<CustomSpawner> specialSpawners, boolean shouldBeTicking, CallbackInfo ci) {
|
private void arclight$init(MinecraftServer minecraftServer, Executor backgroundExecutor, LevelStorageSource.LevelStorageAccess levelSave, ServerLevelData worldInfo, ResourceKey<net.minecraft.world.level.Level> dimension, DimensionType dimensionType, ChunkProgressListener statusListener, ChunkGenerator chunkGenerator, boolean isDebug, long seed, List<CustomSpawner> specialSpawners, boolean shouldBeTicking, CallbackInfo ci) {
|
||||||
this.pvpMode = minecraftServer.isPvpAllowed();
|
this.pvpMode = minecraftServer.isPvpAllowed();
|
||||||
this.convertable = levelSave;
|
this.convertable = levelSave;
|
||||||
this.uuid = WorldUUID.getUUID(levelSave.getDimensionPath(this.getDimensionKey()));
|
this.uuid = WorldUUID.getUUID(levelSave.getDimensionPath(this.dimension()));
|
||||||
if (worldInfo instanceof PrimaryLevelData) {
|
if (worldInfo instanceof PrimaryLevelData) {
|
||||||
this.$$worldDataServer = (PrimaryLevelData) worldInfo;
|
this.$$worldDataServer = (PrimaryLevelData) worldInfo;
|
||||||
} else if (worldInfo instanceof DerivedLevelData) {
|
} else if (worldInfo instanceof DerivedLevelData) {
|
||||||
|
@ -139,7 +131,7 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld
|
||||||
this.$$worldDataServer = DelegateWorldInfo.wrap(((DerivedLevelData) worldInfo));
|
this.$$worldDataServer = DelegateWorldInfo.wrap(((DerivedLevelData) worldInfo));
|
||||||
((DerivedWorldInfoBridge) worldInfo).bridge$setDimType(this.getTypeKey());
|
((DerivedWorldInfoBridge) worldInfo).bridge$setDimType(this.getTypeKey());
|
||||||
if (ArclightConfig.spec().getCompat().isSymlinkWorld()) {
|
if (ArclightConfig.spec().getCompat().isSymlinkWorld()) {
|
||||||
WorldSymlink.create((DerivedLevelData) worldInfo, levelSave.getDimensionPath(this.getDimensionKey()));
|
WorldSymlink.create((DerivedLevelData) worldInfo, levelSave.getDimensionPath(this.dimension()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
((ServerChunkProviderBridge) this.chunkSource).bridge$setViewDistance(spigotConfig.viewDistance);
|
((ServerChunkProviderBridge) this.chunkSource).bridge$setViewDistance(spigotConfig.viewDistance);
|
||||||
|
@ -168,11 +160,6 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld
|
||||||
return this.convertable;
|
return this.convertable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "add", at = @At("RETURN"))
|
|
||||||
private void arclight$validEntity(Entity entityIn, CallbackInfo ci) {
|
|
||||||
((EntityBridge) entityIn).bridge$setValid(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "tickNonPassenger", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/entity/Entity;tick()V"))
|
@Inject(method = "tickNonPassenger", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/entity/Entity;tick()V"))
|
||||||
private void arclight$tickPortal(Entity entityIn, CallbackInfo ci) {
|
private void arclight$tickPortal(Entity entityIn, CallbackInfo ci) {
|
||||||
((EntityBridge) entityIn).bridge$postTick();
|
((EntityBridge) entityIn).bridge$postTick();
|
||||||
|
@ -183,11 +170,6 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld
|
||||||
((EntityBridge) passengerEntity).bridge$postTick();
|
((EntityBridge) passengerEntity).bridge$postTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "removeEntityComplete", remap = false, at = @At("RETURN"))
|
|
||||||
private void arclight$invalidEntity(Entity entityIn, boolean keepData, CallbackInfo ci) {
|
|
||||||
((EntityBridge) entityIn).bridge$setValid(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "tickChunk", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
|
@Inject(method = "tickChunk", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
|
||||||
public void arclight$thunder(LevelChunk chunkIn, int randomTickSpeed, CallbackInfo ci) {
|
public void arclight$thunder(LevelChunk chunkIn, int randomTickSpeed, CallbackInfo ci) {
|
||||||
bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.LIGHTNING);
|
bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.LIGHTNING);
|
||||||
|
@ -226,8 +208,7 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld
|
||||||
|
|
||||||
@Inject(method = "save", at = @At("RETURN"))
|
@Inject(method = "save", at = @At("RETURN"))
|
||||||
private void arclight$saveLevelDat(ProgressListener progress, boolean flush, boolean skipSave, CallbackInfo ci) {
|
private void arclight$saveLevelDat(ProgressListener progress, boolean flush, boolean skipSave, CallbackInfo ci) {
|
||||||
if (this.serverLevelData instanceof PrimaryLevelData) {
|
if (this.serverLevelData instanceof PrimaryLevelData worldInfo) {
|
||||||
PrimaryLevelData worldInfo = (PrimaryLevelData) this.serverLevelData;
|
|
||||||
worldInfo.setWorldBorder(this.getWorldBorder().createSettings());
|
worldInfo.setWorldBorder(this.getWorldBorder().createSettings());
|
||||||
worldInfo.setCustomBossEvents(this.shadow$getServer().getCustomBossEvents().save());
|
worldInfo.setCustomBossEvents(this.shadow$getServer().getCustomBossEvents().save());
|
||||||
this.convertable.saveDataTag(this.shadow$getServer().registryHolder, worldInfo, this.shadow$getServer().getPlayerList().getSingleplayerData());
|
this.convertable.saveDataTag(this.shadow$getServer().registryHolder, worldInfo, this.shadow$getServer().getPlayerList().getSingleplayerData());
|
||||||
|
@ -317,13 +298,17 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld
|
||||||
return addWithUUID(entity);
|
return addWithUUID(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addEntityTeleport(Entity entity, CreatureSpawnEvent.SpawnReason reason) {
|
||||||
|
addEntity(entity, reason);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean bridge$addEntitySerialized(Entity entity, CreatureSpawnEvent.SpawnReason reason) {
|
public boolean bridge$addEntitySerialized(Entity entity, CreatureSpawnEvent.SpawnReason reason) {
|
||||||
return addEntitySerialized(entity, reason);
|
return addEntitySerialized(entity, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addAllEntitiesSafely(Entity entity, CreatureSpawnEvent.SpawnReason reason) {
|
public boolean addAllEntitiesSafely(Entity entity, CreatureSpawnEvent.SpawnReason reason) {
|
||||||
if (entity.getSelfAndPassengers().anyMatch(this::isUUIDUsed)) {
|
if (entity.getSelfAndPassengers().map(Entity::getUUID).anyMatch(this.entityManager::isLoaded)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this.bridge$addAllEntities(entity, reason);
|
return this.bridge$addAllEntities(entity, reason);
|
||||||
|
@ -351,14 +336,20 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld
|
||||||
@Overwrite
|
@Overwrite
|
||||||
@Nullable
|
@Nullable
|
||||||
public MapItemSavedData getMapData(String mapName) {
|
public MapItemSavedData getMapData(String mapName) {
|
||||||
return this.shadow$getServer().overworld().getDataStorage().get(() -> {
|
return this.shadow$getServer().overworld().getDataStorage().get((nbt) -> {
|
||||||
MapItemSavedData newMap = new MapItemSavedData(mapName);
|
MapItemSavedData newMap = MapItemSavedData.load(nbt);
|
||||||
|
((MapDataBridge) newMap).bridge$setId(mapName);
|
||||||
MapInitializeEvent event = new MapInitializeEvent(((MapDataBridge) newMap).bridge$getMapView());
|
MapInitializeEvent event = new MapInitializeEvent(((MapDataBridge) newMap).bridge$getMapView());
|
||||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||||
return newMap;
|
return newMap;
|
||||||
}, mapName);
|
}, mapName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject(method = "setMapData", at = @At("HEAD"))
|
||||||
|
private void arclight$mapSetId(String id, MapItemSavedData data, CallbackInfo ci) {
|
||||||
|
((MapDataBridge) data).bridge$setId(id);
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(method = "blockUpdated", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;updateNeighborsAt(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;)V"))
|
@Inject(method = "blockUpdated", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;updateNeighborsAt(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;)V"))
|
||||||
private void arclight$returnIfPopulate(BlockPos pos, Block block, CallbackInfo ci) {
|
private void arclight$returnIfPopulate(BlockPos pos, Block block, CallbackInfo ci) {
|
||||||
if (populating) {
|
if (populating) {
|
||||||
|
@ -366,64 +357,9 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockEntity bridge$getTileEntity(BlockPos blockPos) {
|
|
||||||
return this.getTileEntity(blockPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockEntity hack$getTileEntity(BlockPos pos) {
|
|
||||||
return this.getTileEntity(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockEntity getTileEntity(BlockPos pos) {
|
|
||||||
return getTileEntity(pos, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockEntity getTileEntity(BlockPos pos, boolean validate) {
|
public BlockEntity getTileEntity(BlockPos pos, boolean validate) {
|
||||||
BlockEntity result = super.getTileEntity(pos);
|
return this.getBlockEntity(pos);
|
||||||
if (!validate || Thread.currentThread() != arclight$getMainThread()) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockState state = getBlockState(pos);
|
|
||||||
Block type = state.getBlock();
|
|
||||||
|
|
||||||
if (result != null && type != Blocks.AIR) {
|
|
||||||
if (!result.getType().isValid(type)) {
|
|
||||||
result = fixTileEntity(pos, state, type, result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private BlockEntity fixTileEntity(BlockPos pos, Block type, BlockEntity found) {
|
|
||||||
return fixTileEntity(pos, getBlockState(pos), type, found);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BlockEntity fixTileEntity(BlockPos pos, BlockState state, Block type, BlockEntity found) {
|
|
||||||
ResourceLocation registryName = found.getType().getRegistryName();
|
|
||||||
if (registryName == null || !registryName.getNamespace().equals("minecraft")) {
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
ResourceLocation blockType = type.getRegistryName();
|
|
||||||
if (blockType == null || !blockType.getNamespace().equals("minecraft")) {
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
this.getServer().getLogger().log(Level.SEVERE, "Block at {0}, {1}, {2} is {3} but has {4}" + ". "
|
|
||||||
+ "Bukkit will attempt to fix this, but there may be additional damage that we cannot recover.", new Object[]{pos.getX(), pos.getY(), pos.getZ(), type, found});
|
|
||||||
|
|
||||||
if (type.hasTileEntity(state)) {
|
|
||||||
BlockEntity replacement = type.createTileEntity(state, (BlockGetter) this);
|
|
||||||
if (replacement == null) return found;
|
|
||||||
replacement.setLevelAndPosition(((net.minecraft.world.level.Level) (Object) this), pos);
|
|
||||||
this.setTileEntity(pos, replacement);
|
|
||||||
return replacement;
|
|
||||||
} else {
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setDayTime(J)V"))
|
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setDayTime(J)V"))
|
||||||
|
@ -433,7 +369,6 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld
|
||||||
arclight$timeSkipCancelled = event.isCancelled();
|
arclight$timeSkipCancelled = event.isCancelled();
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
world.setDayTime(this.getDayTime() + event.getSkipAmount());
|
world.setDayTime(this.getDayTime() + event.getSkipAmount());
|
||||||
this.allPlayersSleeping = this.players.stream().allMatch(LivingEntity::isSleeping);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package io.izzel.arclight.common.mixin.core.server.level;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
||||||
|
import io.izzel.arclight.common.bridge.world.storage.MapDataBridge;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
||||||
|
import net.minecraft.world.level.storage.DimensionDataStorage;
|
||||||
|
import net.minecraftforge.fmllegacy.server.ServerLifecycleHooks;
|
||||||
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Mixin(targets = "net/minecraft/server/level/ServerLevel$EntityCallbacks")
|
||||||
|
public class ServerLevel_EntityCallbacksMixin {
|
||||||
|
|
||||||
|
@Inject(method = "onTrackingStart", at = @At("RETURN"))
|
||||||
|
private void arclight$valid(Entity entity, CallbackInfo ci) {
|
||||||
|
((EntityBridge) entity).bridge$setValid(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "onTrackingEnd", at = @At("HEAD"))
|
||||||
|
private void arclight$entityCleanup(Entity entity, CallbackInfo ci) {
|
||||||
|
if (entity instanceof Player player) {
|
||||||
|
for (ServerLevel serverLevel : ServerLifecycleHooks.getCurrentServer().levels.values()) {
|
||||||
|
DimensionDataStorage worldData = serverLevel.getDataStorage();
|
||||||
|
for (Object o : worldData.cache.values()) {
|
||||||
|
if (o instanceof MapItemSavedData map) {
|
||||||
|
map.carriedByPlayers.remove(player);
|
||||||
|
((MapDataBridge) map).bridge$getCarriedBy().removeIf(holdingPlayer -> holdingPlayer.player == entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (((EntityBridge) entity).bridge$getBukkitEntity() instanceof InventoryHolder holder) {
|
||||||
|
for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(holder.getInventory().getViewers())) {
|
||||||
|
h.closeInventory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "onTrackingEnd", at = @At("RETURN"))
|
||||||
|
private void arclight$invalid(Entity entity, CallbackInfo ci) {
|
||||||
|
((EntityBridge) entity).bridge$setValid(true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,12 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.server;
|
package io.izzel.arclight.common.mixin.core.server.level;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.world.server.TicketManagerBridge;
|
import io.izzel.arclight.common.bridge.world.server.TicketManagerBridge;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
||||||
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.server.level.DistanceManager;
|
import net.minecraft.server.level.DistanceManager;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.server.level.Ticket;
|
import net.minecraft.server.level.Ticket;
|
||||||
import net.minecraft.server.level.TicketType;
|
import net.minecraft.server.level.TicketType;
|
||||||
import net.minecraft.util.SortedArraySet;
|
import net.minecraft.util.SortedArraySet;
|
||||||
|
@ -12,6 +15,10 @@ import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
|
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.callback.LocalCapture;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
@ -27,14 +34,11 @@ public abstract class TicketManagerMixin implements TicketManagerBridge {
|
||||||
@Invoker("purgeStaleTickets") public abstract void bridge$tick();
|
@Invoker("purgeStaleTickets") public abstract void bridge$tick();
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
@SuppressWarnings("unused") // mock
|
@Inject(method = "removePlayer", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", remap = false, target = "Lit/unimi/dsi/fastutil/objects/ObjectSet;remove(Ljava/lang/Object;)Z"))
|
||||||
public <T> boolean func_219356_a(TicketType<T> type, ChunkPos pos, int level, T value) {
|
private void arclight$remove(SectionPos p_140829_, ServerPlayer p_140830_, CallbackInfo ci, ObjectSet<?> set) {
|
||||||
return addTicketAtLevel(type, pos, level, value);
|
if (set == null) {
|
||||||
}
|
ci.cancel();
|
||||||
|
}
|
||||||
@SuppressWarnings("unused") // mock
|
|
||||||
public <T> boolean func_219345_b(TicketType<T> type, ChunkPos pos, int level, T value) {
|
|
||||||
return removeTicketAtLevel(type, pos, level, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> boolean addTicketAtLevel(TicketType<T> type, ChunkPos pos, int level, T value) {
|
public <T> boolean addTicketAtLevel(TicketType<T> type, ChunkPos pos, int level, T value) {
|
||||||
|
@ -57,12 +61,7 @@ public abstract class TicketManagerMixin implements TicketManagerBridge {
|
||||||
return removeTicketAtLevel(type, pos, level, value);
|
return removeTicketAtLevel(type, pos, level, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused") // mock
|
boolean removeTicket(long chunkPosIn, Ticket<?> ticketIn) {
|
||||||
private boolean func_219349_b(long chunkPosIn, Ticket<?> ticketIn) {
|
|
||||||
return removeTicket(chunkPosIn, ticketIn);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean removeTicket(long chunkPosIn, Ticket<?> ticketIn) {
|
|
||||||
SortedArraySet<Ticket<?>> ticketSet = this.getTickets(chunkPosIn);
|
SortedArraySet<Ticket<?>> ticketSet = this.getTickets(chunkPosIn);
|
||||||
boolean removed = false;
|
boolean removed = false;
|
||||||
if (ticketSet.remove(ticketIn)) {
|
if (ticketSet.remove(ticketIn)) {
|
||||||
|
@ -80,12 +79,7 @@ public abstract class TicketManagerMixin implements TicketManagerBridge {
|
||||||
return removeTicket(chunkPos, ticket);
|
return removeTicket(chunkPos, ticket);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused") // mock
|
boolean addTicket(long chunkPosIn, Ticket<?> ticketIn) {
|
||||||
private boolean func_219347_a(long chunkPosIn, Ticket<?> ticketIn) {
|
|
||||||
return addTicket(chunkPosIn, ticketIn);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean addTicket(long chunkPosIn, Ticket<?> ticketIn) {
|
|
||||||
SortedArraySet<Ticket<?>> ticketSet = this.getTickets(chunkPosIn);
|
SortedArraySet<Ticket<?>> ticketSet = this.getTickets(chunkPosIn);
|
||||||
int level = getTicketLevelAt(ticketSet);
|
int level = getTicketLevelAt(ticketSet);
|
||||||
Ticket<?> ticket = ticketSet.addOrGet(ticketIn);
|
Ticket<?> ticket = ticketSet.addOrGet(ticketIn);
|
|
@ -1,4 +1,4 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.server;
|
package io.izzel.arclight.common.mixin.core.server.level;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.world.server.TicketTypeBridge;
|
import io.izzel.arclight.common.bridge.world.server.TicketTypeBridge;
|
||||||
import net.minecraft.server.level.TicketType;
|
import net.minecraft.server.level.TicketType;
|
|
@ -557,7 +557,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
|
||||||
File file2;
|
File file2;
|
||||||
File file = this.server.getWorldPath(LevelResource.PLAYER_STATS_DIR).toFile();
|
File file = this.server.getWorldPath(LevelResource.PLAYER_STATS_DIR).toFile();
|
||||||
File file1 = new File(file, uuid + ".json");
|
File file1 = new File(file, uuid + ".json");
|
||||||
if (!file1.exists() && (file2 = new File(file, String.valueOf(displayName) + ".json")).exists() && file2.isFile()) {
|
if (!file1.exists() && (file2 = new File(file, displayName + ".json")).exists() && file2.isFile()) {
|
||||||
file2.renameTo(file1);
|
file2.renameTo(file1);
|
||||||
}
|
}
|
||||||
serverstatisticmanager = new ServerStatsCounter(this.server, file1);
|
serverstatisticmanager = new ServerStatsCounter(this.server, file1);
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.NonNullList;
|
|
||||||
import net.minecraft.world.Container;
|
|
||||||
import net.minecraft.world.Containers;
|
|
||||||
import net.minecraft.world.SimpleContainer;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.item.crafting.RecipeType;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
|
||||||
import net.minecraft.world.level.block.entity.CampfireBlockEntity;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
|
||||||
import org.bukkit.craftbukkit.v.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.event.block.BlockCookEvent;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
|
|
||||||
@Mixin(CampfireBlockEntity.class)
|
|
||||||
public abstract class CampfireTileEntityMixin extends BlockEntity {
|
|
||||||
|
|
||||||
// @formatter:off
|
|
||||||
@Shadow @Final private NonNullList<ItemStack> items;
|
|
||||||
@Shadow @Final public int[] cookingProgress;
|
|
||||||
@Shadow @Final public int[] cookingTime;
|
|
||||||
@Shadow protected abstract void markUpdated();
|
|
||||||
// @formatter:on
|
|
||||||
|
|
||||||
public CampfireTileEntityMixin(BlockEntityType<?> tileEntityTypeIn) {
|
|
||||||
super(tileEntityTypeIn);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author IzzelAliz
|
|
||||||
* @reason
|
|
||||||
*/
|
|
||||||
@Overwrite
|
|
||||||
private void cook() {
|
|
||||||
for (int i = 0; i < this.items.size(); ++i) {
|
|
||||||
ItemStack before = this.items.get(i);
|
|
||||||
if (!before.isEmpty()) {
|
|
||||||
++this.cookingProgress[i];
|
|
||||||
if (this.cookingProgress[i] >= this.cookingTime[i]) {
|
|
||||||
Container iinventory = new SimpleContainer(before);
|
|
||||||
ItemStack after = this.level.getRecipeManager().getRecipeFor(RecipeType.CAMPFIRE_COOKING, iinventory,
|
|
||||||
this.level).map((cookingRecipe) -> cookingRecipe.assemble(iinventory)).orElse(before);
|
|
||||||
BlockPos blockpos = this.getBlockPos();
|
|
||||||
|
|
||||||
CraftItemStack craftBefore = CraftItemStack.asCraftMirror(before);
|
|
||||||
org.bukkit.inventory.ItemStack bukkitAfter = CraftItemStack.asBukkitCopy(after);
|
|
||||||
BlockCookEvent event = new BlockCookEvent(CraftBlock.at(this.level, this.worldPosition), craftBefore, bukkitAfter);
|
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
|
||||||
if (event.isCancelled()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ItemStack cookFinal = CraftItemStack.asNMSCopy(event.getResult());
|
|
||||||
|
|
||||||
Containers.dropItemStack(this.level, blockpos.getX(), blockpos.getY(), blockpos.getZ(), cookFinal);
|
|
||||||
this.items.set(i, ItemStack.EMPTY);
|
|
||||||
this.markUpdated();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,119 +0,0 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
|
|
||||||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
|
||||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
|
||||||
import org.bukkit.entity.HumanEntity;
|
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
|
||||||
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.Redirect;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.NonNullList;
|
|
||||||
import net.minecraft.util.Mth;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraft.world.level.block.Blocks;
|
|
||||||
import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
|
||||||
|
|
||||||
@Mixin(ChestBlockEntity.class)
|
|
||||||
public abstract class ChestTileEntityMixin extends LockableTileEntityMixin {
|
|
||||||
|
|
||||||
// @formatter:off
|
|
||||||
@Shadow private NonNullList<ItemStack> items;
|
|
||||||
@Shadow public int openCount;
|
|
||||||
// @formatter:on
|
|
||||||
|
|
||||||
public List<HumanEntity> transaction = new ArrayList<>();
|
|
||||||
private int maxStack = IInventoryBridge.MAX_STACK;
|
|
||||||
public boolean opened;
|
|
||||||
|
|
||||||
@Inject(method = "startOpen", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/ChestBlockEntity;signalOpenCount()V"))
|
|
||||||
public void arclight$openRedstone(Player player, CallbackInfo ci) {
|
|
||||||
if (this.level == null) {
|
|
||||||
ci.cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int oldPower = Mth.clamp(this.openCount - 1, 0, 15);
|
|
||||||
if (this.getBlockState().getBlock() == Blocks.TRAPPED_CHEST) {
|
|
||||||
int newPower = Mth.clamp(this.openCount, 0, 15);
|
|
||||||
|
|
||||||
if (oldPower != newPower) {
|
|
||||||
CraftEventFactory.callRedstoneChange(level, worldPosition, oldPower, newPower);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "stopOpen", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/ChestBlockEntity;signalOpenCount()V"))
|
|
||||||
public void arclight$closeRedstone(Player player, CallbackInfo ci) {
|
|
||||||
int oldPower = Mth.clamp(this.openCount + 1, 0, 15);
|
|
||||||
if (this.getBlockState().getBlock() == Blocks.TRAPPED_CHEST) {
|
|
||||||
int newPower = Mth.clamp(this.openCount, 0, 15);
|
|
||||||
|
|
||||||
if (oldPower != newPower) {
|
|
||||||
CraftEventFactory.callRedstoneChange(level, worldPosition, oldPower, newPower);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "tick", cancellable = true, at = @At(value = "FIELD", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/level/block/entity/ChestBlockEntity;oOpenness:F"))
|
|
||||||
private void arclight$openByApi(CallbackInfo ci) {
|
|
||||||
if (opened) {
|
|
||||||
this.openCount--;
|
|
||||||
ci.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(method = "signalOpenCount", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;blockEvent(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;II)V"))
|
|
||||||
private void arclight$soundIfByPlayer(Level world, BlockPos pos, Block blockIn, int eventID, int eventParam) {
|
|
||||||
if (!opened) world.blockEvent(pos, blockIn, eventID, eventParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> getContents() {
|
|
||||||
return this.items;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onOpen(CraftHumanEntity who) {
|
|
||||||
transaction.add(who);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClose(CraftHumanEntity who) {
|
|
||||||
transaction.remove(who);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<HumanEntity> getViewers() {
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setOwner(InventoryHolder owner) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMaxStackSize() {
|
|
||||||
if (maxStack == 0) maxStack = IInventoryBridge.MAX_STACK;
|
|
||||||
return maxStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMaxStackSize(int size) {
|
|
||||||
this.maxStack = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onlyOpsCanSetNbt() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,96 +0,0 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
|
||||||
import com.google.common.cache.LoadingCache;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.util.concurrent.Futures;
|
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import com.mysql.jdbc.StringUtils;
|
|
||||||
import io.izzel.arclight.common.bridge.server.MinecraftServerBridge;
|
|
||||||
import io.izzel.arclight.common.mod.util.ArclightHeadLoader;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.craftbukkit.v.CraftServer;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import net.minecraft.world.level.block.entity.SkullBlockEntity;
|
|
||||||
|
|
||||||
@Mixin(SkullBlockEntity.class)
|
|
||||||
public abstract class SkullTileEntityMixin extends TileEntityMixin {
|
|
||||||
|
|
||||||
// @formatter:off
|
|
||||||
@Shadow public GameProfile owner;
|
|
||||||
// @formatter:on
|
|
||||||
|
|
||||||
private static ExecutorService executor = Executors.newFixedThreadPool(3,
|
|
||||||
new ThreadFactoryBuilder()
|
|
||||||
.setNameFormat("Head Conversion Thread - %1$d")
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
|
|
||||||
private static LoadingCache<String, GameProfile> skinCache = CacheBuilder.newBuilder().maximumSize(5000L).expireAfterAccess(60L, TimeUnit.MINUTES).build(new ArclightHeadLoader());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author IzzelAliz
|
|
||||||
* @reason
|
|
||||||
*/
|
|
||||||
@Overwrite
|
|
||||||
private void updateOwnerProfile() {
|
|
||||||
GameProfile profile = this.owner;
|
|
||||||
b(profile, input -> {
|
|
||||||
owner = input;
|
|
||||||
markDirty();
|
|
||||||
return false;
|
|
||||||
}, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"UnusedReturnValue", "ConstantConditions"})
|
|
||||||
private static Future<GameProfile> b(GameProfile gameprofile, Predicate<GameProfile> callback, boolean sync) {
|
|
||||||
if (gameprofile != null && !StringUtils.isNullOrEmpty(gameprofile.getName())) {
|
|
||||||
if (gameprofile.isComplete() && gameprofile.getProperties().containsKey("textures")) {
|
|
||||||
callback.apply(gameprofile);
|
|
||||||
} else if (Bukkit.getServer() == null || ((CraftServer) Bukkit.getServer()).getServer() == null) {
|
|
||||||
callback.apply(gameprofile);
|
|
||||||
} else {
|
|
||||||
GameProfile profile = skinCache.getIfPresent(gameprofile.getName().toLowerCase(Locale.ROOT));
|
|
||||||
if (profile != null && Iterables.getFirst((profile.getProperties()).get("textures"), null) != null) {
|
|
||||||
callback.apply(profile);
|
|
||||||
return Futures.immediateFuture(profile);
|
|
||||||
}
|
|
||||||
Callable<GameProfile> callable = () -> {
|
|
||||||
GameProfile profile1 = skinCache.getUnchecked(gameprofile.getName().toLowerCase(Locale.ROOT));
|
|
||||||
((MinecraftServerBridge) ((CraftServer) Bukkit.getServer()).getServer()).bridge$queuedProcess(() -> {
|
|
||||||
if (profile1 == null) {
|
|
||||||
callback.apply(gameprofile);
|
|
||||||
} else {
|
|
||||||
callback.apply(profile1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return profile1;
|
|
||||||
};
|
|
||||||
if (sync) {
|
|
||||||
try {
|
|
||||||
return Futures.immediateFuture(callable.call());
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Throwables.throwIfUnchecked(ex);
|
|
||||||
throw new RuntimeException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return executor.submit(callable);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback.apply(gameprofile);
|
|
||||||
}
|
|
||||||
return Futures.immediateFuture(gameprofile);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,6 +7,33 @@ import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.ExplosionBridge;
|
import io.izzel.arclight.common.bridge.world.ExplosionBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.sounds.SoundEvents;
|
||||||
|
import net.minecraft.sounds.SoundSource;
|
||||||
|
import net.minecraft.util.Mth;
|
||||||
|
import net.minecraft.world.damagesource.DamageSource;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.entity.item.FallingBlockEntity;
|
||||||
|
import net.minecraft.world.entity.item.PrimedTnt;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.enchantment.ProtectionEnchantment;
|
||||||
|
import net.minecraft.world.level.Explosion;
|
||||||
|
import net.minecraft.world.level.ExplosionDamageCalculator;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.BaseFireBlock;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.gameevent.GameEvent;
|
||||||
|
import net.minecraft.world.level.material.FluidState;
|
||||||
|
import net.minecraft.world.level.storage.loot.LootContext;
|
||||||
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||||
|
import net.minecraft.world.phys.AABB;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||||
|
@ -29,32 +56,6 @@ import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.sounds.SoundEvents;
|
|
||||||
import net.minecraft.sounds.SoundSource;
|
|
||||||
import net.minecraft.util.Mth;
|
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
|
||||||
import net.minecraft.world.entity.item.FallingBlockEntity;
|
|
||||||
import net.minecraft.world.entity.item.PrimedTnt;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.item.enchantment.ProtectionEnchantment;
|
|
||||||
import net.minecraft.world.level.Explosion;
|
|
||||||
import net.minecraft.world.level.ExplosionDamageCalculator;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.block.BaseFireBlock;
|
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.material.FluidState;
|
|
||||||
import net.minecraft.world.level.storage.loot.LootContext;
|
|
||||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
|
||||||
import net.minecraft.world.phys.AABB;
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
|
||||||
|
|
||||||
@Mixin(Explosion.class)
|
@Mixin(Explosion.class)
|
||||||
public abstract class ExplosionMixin implements ExplosionBridge {
|
public abstract class ExplosionMixin implements ExplosionBridge {
|
||||||
|
@ -77,9 +78,9 @@ public abstract class ExplosionMixin implements ExplosionBridge {
|
||||||
@Shadow @Final private boolean fire;
|
@Shadow @Final private boolean fire;
|
||||||
@Shadow @Final private Random random;
|
@Shadow @Final private Random random;
|
||||||
@Shadow private static void addBlockDrops(ObjectArrayList<Pair<ItemStack, BlockPos>> dropPositionArray, ItemStack stack, BlockPos pos) { }
|
@Shadow private static void addBlockDrops(ObjectArrayList<Pair<ItemStack, BlockPos>> dropPositionArray, ItemStack stack, BlockPos pos) { }
|
||||||
|
@Shadow @Final private ExplosionDamageCalculator damageCalculator;
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
@Shadow @Final private ExplosionDamageCalculator damageCalculator;
|
|
||||||
|
|
||||||
@Inject(method = "<init>(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/Entity;DDDFZLnet/minecraft/world/level/Explosion$BlockInteraction;)V",
|
@Inject(method = "<init>(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/Entity;DDDFZLnet/minecraft/world/level/Explosion$BlockInteraction;)V",
|
||||||
at = @At("RETURN"))
|
at = @At("RETURN"))
|
||||||
|
@ -96,6 +97,7 @@ public abstract class ExplosionMixin implements ExplosionBridge {
|
||||||
if (this.radius < 0.1F) {
|
if (this.radius < 0.1F) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.level.gameEvent(this.source, GameEvent.EXPLODE, new BlockPos(this.x, this.y, this.z));
|
||||||
Set<BlockPos> set = Sets.newHashSet();
|
Set<BlockPos> set = Sets.newHashSet();
|
||||||
int i = 16;
|
int i = 16;
|
||||||
|
|
||||||
|
@ -119,6 +121,11 @@ public abstract class ExplosionMixin implements ExplosionBridge {
|
||||||
BlockPos blockpos = new BlockPos(d4, d6, d8);
|
BlockPos blockpos = new BlockPos(d4, d6, d8);
|
||||||
BlockState blockstate = this.level.getBlockState(blockpos);
|
BlockState blockstate = this.level.getBlockState(blockpos);
|
||||||
FluidState fluidstate = this.level.getFluidState(blockpos);
|
FluidState fluidstate = this.level.getFluidState(blockpos);
|
||||||
|
|
||||||
|
if (!this.level.isInWorldBounds(blockpos)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Optional<Float> optional = this.damageCalculator.getBlockExplosionResistance((Explosion) (Object) this, this.level, blockpos, blockstate, fluidstate);
|
Optional<Float> optional = this.damageCalculator.getBlockExplosionResistance((Explosion) (Object) this, this.level, blockpos, blockstate, fluidstate);
|
||||||
if (optional.isPresent()) {
|
if (optional.isPresent()) {
|
||||||
f -= (optional.get() + 0.3F) * 0.3F;
|
f -= (optional.get() + 0.3F) * 0.3F;
|
||||||
|
@ -151,12 +158,12 @@ public abstract class ExplosionMixin implements ExplosionBridge {
|
||||||
|
|
||||||
for (Entity entity : list) {
|
for (Entity entity : list) {
|
||||||
if (!entity.ignoreExplosion()) {
|
if (!entity.ignoreExplosion()) {
|
||||||
double d12 = Mth.sqrt(entity.distanceToSqr(vec3d)) / f3;
|
double d12 = Math.sqrt(entity.distanceToSqr(vec3d)) / f3;
|
||||||
if (d12 <= 1.0D) {
|
if (d12 <= 1.0D) {
|
||||||
double d5 = entity.getX() - this.x;
|
double d5 = entity.getX() - this.x;
|
||||||
double d7 = entity.getEyeY() - this.y;
|
double d7 = entity.getEyeY() - this.y;
|
||||||
double d9 = entity.getZ() - this.z;
|
double d9 = entity.getZ() - this.z;
|
||||||
double d13 = Mth.sqrt(d5 * d5 + d7 * d7 + d9 * d9);
|
double d13 = Math.sqrt(d5 * d5 + d7 * d7 + d9 * d9);
|
||||||
if (d13 != 0.0D) {
|
if (d13 != 0.0D) {
|
||||||
d5 = d5 / d13;
|
d5 = d5 / d13;
|
||||||
d7 = d7 / d13;
|
d7 = d7 / d13;
|
||||||
|
@ -178,9 +185,8 @@ public abstract class ExplosionMixin implements ExplosionBridge {
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.setDeltaMovement(entity.getDeltaMovement().add(d5 * d11, d7 * d11, d9 * d11));
|
entity.setDeltaMovement(entity.getDeltaMovement().add(d5 * d11, d7 * d11, d9 * d11));
|
||||||
if (entity instanceof Player) {
|
if (entity instanceof Player playerentity) {
|
||||||
Player playerentity = (Player) entity;
|
if (!playerentity.isSpectator() && (!playerentity.isCreative() || !playerentity.getAbilities().flying)) {
|
||||||
if (!playerentity.isSpectator() && (!playerentity.isCreative() || !playerentity.abilities.flying)) {
|
|
||||||
this.hitPlayers.put(playerentity, new Vec3(d5 * d10, d7 * d10, d9 * d10));
|
this.hitPlayers.put(playerentity, new Vec3(d5 * d10, d7 * d10, d9 * d10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,12 +237,12 @@ public abstract class ExplosionMixin implements ExplosionBridge {
|
||||||
for (BlockPos blockpos : this.toBlow) {
|
for (BlockPos blockpos : this.toBlow) {
|
||||||
BlockState blockstate = this.level.getBlockState(blockpos);
|
BlockState blockstate = this.level.getBlockState(blockpos);
|
||||||
Block block = blockstate.getBlock();
|
Block block = blockstate.getBlock();
|
||||||
if (!blockstate.isAir(this.level, blockpos)) {
|
if (!blockstate.isAir()) {
|
||||||
BlockPos blockpos1 = blockpos.immutable();
|
BlockPos blockpos1 = blockpos.immutable();
|
||||||
this.level.getProfiler().push("explosion_blocks");
|
this.level.getProfiler().push("explosion_blocks");
|
||||||
if (blockstate.canDropFromExplosion(this.level, blockpos, (Explosion) (Object) this) && this.level instanceof ServerLevel) {
|
if (blockstate.canDropFromExplosion(this.level, blockpos, (Explosion) (Object) this) && this.level instanceof ServerLevel) {
|
||||||
BlockEntity tileentity = blockstate.hasTileEntity() ? this.level.getBlockEntity(blockpos) : null;
|
BlockEntity tileentity = blockstate.hasBlockEntity() ? this.level.getBlockEntity(blockpos) : null;
|
||||||
LootContext.Builder lootcontext$builder = (new LootContext.Builder((ServerLevel)this.level)).withRandom(this.level.random).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockpos)).withParameter(LootContextParams.TOOL, ItemStack.EMPTY).withOptionalParameter(LootContextParams.BLOCK_ENTITY, tileentity).withOptionalParameter(LootContextParams.THIS_ENTITY, this.source);
|
LootContext.Builder lootcontext$builder = (new LootContext.Builder((ServerLevel) this.level)).withRandom(this.level.random).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockpos)).withParameter(LootContextParams.TOOL, ItemStack.EMPTY).withOptionalParameter(LootContextParams.BLOCK_ENTITY, tileentity).withOptionalParameter(LootContextParams.THIS_ENTITY, this.source);
|
||||||
if (this.blockInteraction == Explosion.BlockInteraction.DESTROY || yield < 1.0F) {
|
if (this.blockInteraction == Explosion.BlockInteraction.DESTROY || yield < 1.0F) {
|
||||||
lootcontext$builder.withParameter(LootContextParams.EXPLOSION_RADIUS, 1.0F / yield);
|
lootcontext$builder.withParameter(LootContextParams.EXPLOSION_RADIUS, 1.0F / yield);
|
||||||
}
|
}
|
||||||
|
@ -247,6 +253,7 @@ public abstract class ExplosionMixin implements ExplosionBridge {
|
||||||
}
|
}
|
||||||
|
|
||||||
blockstate.onBlockExploded(this.level, blockpos, (Explosion) (Object) this);
|
blockstate.onBlockExploded(this.level, blockpos, (Explosion) (Object) this);
|
||||||
|
block.wasExploded(this.level, blockpos, (Explosion) (Object) this);
|
||||||
this.level.getProfiler().pop();
|
this.level.getProfiler().pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world;
|
package io.izzel.arclight.common.mixin.core.world;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.world.server.ServerWorldBridge;
|
import io.izzel.arclight.common.bridge.world.server.ServerWorldBridge;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
|
import net.minecraft.world.level.ServerLevelAccessor;
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
|
||||||
import net.minecraft.world.level.ServerLevelAccessor;
|
|
||||||
|
|
||||||
@Mixin(ServerLevelAccessor.class)
|
@Mixin(ServerLevelAccessor.class)
|
||||||
public interface IServerWorldMixin extends LevelAccessor, ServerWorldBridge {
|
public interface IServerWorldMixin extends LevelAccessor, ServerWorldBridge {
|
||||||
|
@ -46,7 +46,7 @@ public interface IServerWorldMixin extends LevelAccessor, ServerWorldBridge {
|
||||||
bridge$pushAddEntityReason(reason);
|
bridge$pushAddEntityReason(reason);
|
||||||
this.addFreshEntity(next);
|
this.addFreshEntity(next);
|
||||||
}
|
}
|
||||||
return !entity.removed;
|
return !entity.isRemoved();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package io.izzel.arclight.common.mixin.core.util;
|
package io.izzel.arclight.common.mixin.core.world.damagesource;
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import io.izzel.arclight.common.bridge.util.DamageSourceBridge;
|
import io.izzel.arclight.common.bridge.util.DamageSourceBridge;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
import net.minecraft.world.damagesource.DamageSource;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
@Mixin(DamageSource.class)
|
@Mixin(DamageSource.class)
|
||||||
public abstract class DamageSourceMixin implements DamageSourceBridge {
|
public abstract class DamageSourceMixin implements DamageSourceBridge {
|
|
@ -1,4 +1,4 @@
|
||||||
package io.izzel.arclight.common.mixin.core.util;
|
package io.izzel.arclight.common.mixin.core.world.damagesource;
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
|
@ -413,8 +413,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
|
||||||
|
|
||||||
@Inject(method = "move", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity$MovementEmission;emitsAnything()Z"))
|
@Inject(method = "move", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity$MovementEmission;emitsAnything()Z"))
|
||||||
private void arclight$move$blockCollide(MoverType typeIn, Vec3 pos, CallbackInfo ci) {
|
private void arclight$move$blockCollide(MoverType typeIn, Vec3 pos, CallbackInfo ci) {
|
||||||
if (horizontalCollision && this.bridge$getBukkitEntity() instanceof Vehicle) {
|
if (horizontalCollision && this.bridge$getBukkitEntity() instanceof Vehicle vehicle) {
|
||||||
Vehicle vehicle = (Vehicle) this.bridge$getBukkitEntity();
|
|
||||||
org.bukkit.block.Block block = ((WorldBridge) this.level).bridge$getWorld().getBlockAt(Mth.floor(this.getX()), Mth.floor(this.getY()), Mth.floor(this.getZ()));
|
org.bukkit.block.Block block = ((WorldBridge) this.level).bridge$getWorld().getBlockAt(Mth.floor(this.getX()), Mth.floor(this.getY()), Mth.floor(this.getZ()));
|
||||||
Vec3 vec3d = this.collide(pos);
|
Vec3 vec3d = this.collide(pos);
|
||||||
if (pos.x > vec3d.x) {
|
if (pos.x > vec3d.x) {
|
||||||
|
@ -506,8 +505,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
|
||||||
@Inject(method = "load", at = @At(value = "RETURN"))
|
@Inject(method = "load", at = @At(value = "RETURN"))
|
||||||
public void arclight$read$ReadBukkitValues(CompoundTag compound, CallbackInfo ci) {
|
public void arclight$read$ReadBukkitValues(CompoundTag compound, CallbackInfo ci) {
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
if ((Object) this instanceof LivingEntity) {
|
if ((Object) this instanceof LivingEntity entity) {
|
||||||
LivingEntity entity = (LivingEntity) (Object) this;
|
|
||||||
|
|
||||||
this.tickCount = compound.getInt("Spigot.ticksLived");
|
this.tickCount = compound.getInt("Spigot.ticksLived");
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ public abstract class EntityTypeMixin<T extends Entity> implements EntityTypeBri
|
||||||
|
|
||||||
@Inject(method = "spawn(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/nbt/CompoundTag;Lnet/minecraft/network/chat/Component;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/MobSpawnType;ZZ)Lnet/minecraft/world/entity/Entity;",
|
@Inject(method = "spawn(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/nbt/CompoundTag;Lnet/minecraft/network/chat/Component;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/MobSpawnType;ZZ)Lnet/minecraft/world/entity/Entity;",
|
||||||
cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At("RETURN"),
|
cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At("RETURN"),
|
||||||
slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;func_242417_l(Lnet/minecraft/world/entity/Entity;)V")))
|
slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V")))
|
||||||
private void arclight$returnIfSuccess(ServerLevel worldIn, CompoundTag compound, Component customName, Player playerIn, BlockPos pos, MobSpawnType reason, boolean p_220342_7_, boolean p_220342_8_, CallbackInfoReturnable<T> cir, T t) {
|
private void arclight$returnIfSuccess(ServerLevel worldIn, CompoundTag compound, Component customName, Player playerIn, BlockPos pos, MobSpawnType reason, boolean p_220342_7_, boolean p_220342_8_, CallbackInfoReturnable<T> cir, T t) {
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
cir.setReturnValue(t.isRemoved() ? null : t);
|
cir.setReturnValue(t.isRemoved() ? null : t);
|
||||||
|
|
|
@ -577,8 +577,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
|
||||||
if (entity1 instanceof net.minecraft.world.entity.player.Player) {
|
if (entity1 instanceof net.minecraft.world.entity.player.Player) {
|
||||||
this.lastHurtByPlayerTime = 100;
|
this.lastHurtByPlayerTime = 100;
|
||||||
this.lastHurtByPlayer = (net.minecraft.world.entity.player.Player) entity1;
|
this.lastHurtByPlayer = (net.minecraft.world.entity.player.Player) entity1;
|
||||||
} else if (entity1 instanceof TamableAnimal) {
|
} else if (entity1 instanceof TamableAnimal wolfentity) {
|
||||||
TamableAnimal wolfentity = (TamableAnimal) entity1;
|
|
||||||
if (wolfentity.isTame()) {
|
if (wolfentity.isTame()) {
|
||||||
this.lastHurtByPlayerTime = 100;
|
this.lastHurtByPlayerTime = 100;
|
||||||
LivingEntity livingentity = wolfentity.getOwner();
|
LivingEntity livingentity = wolfentity.getOwner();
|
||||||
|
@ -910,8 +909,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
|
||||||
if (!itemstack1.isEmpty()) {
|
if (!itemstack1.isEmpty()) {
|
||||||
itemstack1.shrink(1);
|
itemstack1.shrink(1);
|
||||||
}
|
}
|
||||||
if (itemstack != null && (Object) this instanceof ServerPlayer) {
|
if (itemstack != null && (Object) this instanceof ServerPlayer serverplayerentity) {
|
||||||
ServerPlayer serverplayerentity = (ServerPlayer) (Object) this;
|
|
||||||
serverplayerentity.awardStat(Stats.ITEM_USED.get(Items.TOTEM_OF_UNDYING));
|
serverplayerentity.awardStat(Stats.ITEM_USED.get(Items.TOTEM_OF_UNDYING));
|
||||||
CriteriaTriggers.USED_TOTEM.trigger(serverplayerentity, itemstack);
|
CriteriaTriggers.USED_TOTEM.trigger(serverplayerentity, itemstack);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ public class FollowOwnerGoalMixin {
|
||||||
|
|
||||||
private transient boolean arclight$cancelled;
|
private transient boolean arclight$cancelled;
|
||||||
|
|
||||||
@Redirect(method = "maybeTeleportTo", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/TamableAnimal;setLocationAndAngles(DDDFF)V"))
|
@Redirect(method = "maybeTeleportTo", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/TamableAnimal;moveTo(DDDFF)V"))
|
||||||
public void arclight$teleport(TamableAnimal tameableEntity, double x, double y, double z, float yaw, float pitch) {
|
public void arclight$teleport(TamableAnimal tameableEntity, double x, double y, double z, float yaw, float pitch) {
|
||||||
CraftEntity craftEntity = ((EntityBridge) this.tamable).bridge$getBukkitEntity();
|
CraftEntity craftEntity = ((EntityBridge) this.tamable).bridge$getBukkitEntity();
|
||||||
Location location = new Location(craftEntity.getWorld(), x, y, z, yaw, pitch);
|
Location location = new Location(craftEntity.getWorld(), x, y, z, yaw, pitch);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package io.izzel.arclight.common.mixin.core.village;
|
package io.izzel.arclight.common.mixin.core.world.entity.ai.village;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.world.server.ServerWorldBridge;
|
import io.izzel.arclight.common.bridge.world.server.ServerWorldBridge;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
|
@ -26,7 +26,7 @@ public abstract class EnderCrystalMixin extends EntityMixin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "hurt", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/boss/enderdragon/EndCrystal;remove()V"))
|
@Inject(method = "hurt", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/boss/enderdragon/EndCrystal;remove(Lnet/minecraft/world/entity/Entity$RemovalReason;)V"))
|
||||||
private void arclight$entityDamage(DamageSource source, float amount, CallbackInfoReturnable<Boolean> cir) {
|
private void arclight$entityDamage(DamageSource source, float amount, CallbackInfoReturnable<Boolean> cir) {
|
||||||
if (CraftEventFactory.handleNonLivingEntityDamageEvent((EndCrystal) (Object)this, source, amount)) {
|
if (CraftEventFactory.handleNonLivingEntityDamageEvent((EndCrystal) (Object)this, source, amount)) {
|
||||||
cir.setReturnValue(false);
|
cir.setReturnValue(false);
|
||||||
|
|
|
@ -162,13 +162,14 @@ public abstract class ArmorStandMixin extends LivingEntityMixin {
|
||||||
@Override
|
@Override
|
||||||
public void setSlot(net.minecraft.world.entity.EquipmentSlot slotIn, ItemStack stack, boolean silent) {
|
public void setSlot(net.minecraft.world.entity.EquipmentSlot slotIn, ItemStack stack, boolean silent) {
|
||||||
switch (slotIn.getType()) {
|
switch (slotIn.getType()) {
|
||||||
case HAND:
|
case HAND -> {
|
||||||
this.bridge$playEquipSound(stack, silent);
|
this.bridge$playEquipSound(stack, silent);
|
||||||
this.handItems.set(slotIn.getIndex(), stack);
|
this.handItems.set(slotIn.getIndex(), stack);
|
||||||
break;
|
}
|
||||||
case ARMOR:
|
case ARMOR -> {
|
||||||
this.bridge$playEquipSound(stack, silent);
|
this.bridge$playEquipSound(stack, silent);
|
||||||
this.armorItems.set(slotIn.getIndex(), stack);
|
this.armorItems.set(slotIn.getIndex(), stack);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,20 +12,12 @@ import net.minecraft.world.phys.AABB;
|
||||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Mixin(LeashFenceKnotEntity.class)
|
@Mixin(LeashFenceKnotEntity.class)
|
||||||
public abstract class LeashFenceKnotEntityMixin extends HangingEntityMixin {
|
public abstract class LeashFenceKnotEntityMixin extends HangingEntityMixin {
|
||||||
|
|
||||||
@Inject(method = "recalculateBoundingBox", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;updateChunkPos(Lnet/minecraft/world/entity/Entity;)V"))
|
|
||||||
private void arclight$checkIfValid(CallbackInfo ci) {
|
|
||||||
if (!valid) ci.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author IzzelAliz
|
* @author IzzelAliz
|
||||||
* @reason
|
* @reason
|
||||||
|
|
|
@ -39,7 +39,7 @@ public abstract class VillagerMixin extends AbstractVillagerMixin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "thunderHit", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;func_242417_l(Lnet/minecraft/world/entity/Entity;)V"))
|
@Inject(method = "thunderHit", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V"))
|
||||||
private void arclight$transformWitch(ServerLevel serverWorld, LightningBolt lightningBolt, CallbackInfo ci, Witch witchEntity) {
|
private void arclight$transformWitch(ServerLevel serverWorld, LightningBolt lightningBolt, CallbackInfo ci, Witch witchEntity) {
|
||||||
if (CraftEventFactory.callEntityTransformEvent((net.minecraft.world.entity.npc.Villager) (Object) this, witchEntity, EntityTransformEvent.TransformReason.LIGHTNING).isCancelled()) {
|
if (CraftEventFactory.callEntityTransformEvent((net.minecraft.world.entity.npc.Villager) (Object) this, witchEntity, EntityTransformEvent.TransformReason.LIGHTNING).isCancelled()) {
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
|
@ -48,7 +48,7 @@ public abstract class VillagerMixin extends AbstractVillagerMixin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "trySpawnGolem", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;func_242417_l(Lnet/minecraft/world/entity/Entity;)V"))
|
@Inject(method = "trySpawnGolem", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V"))
|
||||||
private void arclight$ironGolemReason(ServerLevel world, CallbackInfoReturnable<IronGolem> cir) {
|
private void arclight$ironGolemReason(ServerLevel world, CallbackInfoReturnable<IronGolem> cir) {
|
||||||
((WorldBridge) world).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE);
|
((WorldBridge) world).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -431,8 +431,7 @@ public abstract class PlayerMixin extends LivingEntityMixin implements PlayerEnt
|
||||||
@Inject(method = "stopSleepInBed", at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/player/Player;sleepCounter:I"))
|
@Inject(method = "stopSleepInBed", at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/player/Player;sleepCounter:I"))
|
||||||
private void arclight$wakeup(boolean flag, boolean flag1, CallbackInfo ci) {
|
private void arclight$wakeup(boolean flag, boolean flag1, CallbackInfo ci) {
|
||||||
BlockPos blockPos = this.getSleepingPos().orElse(null);
|
BlockPos blockPos = this.getSleepingPos().orElse(null);
|
||||||
if (this.bridge$getBukkitEntity() instanceof Player) {
|
if (this.bridge$getBukkitEntity() instanceof Player player) {
|
||||||
Player player = (Player) this.bridge$getBukkitEntity();
|
|
||||||
Block bed;
|
Block bed;
|
||||||
if (blockPos != null) {
|
if (blockPos != null) {
|
||||||
bed = CraftBlock.at(this.level, blockPos);
|
bed = CraftBlock.at(this.level, blockPos);
|
||||||
|
|
|
@ -1,18 +1,7 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.entity.projectile;
|
package io.izzel.arclight.common.mixin.core.world.entity.projectile;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.entity.LivingEntityBridge;
|
import io.izzel.arclight.common.bridge.entity.LivingEntityBridge;
|
||||||
import org.bukkit.event.entity.EntityPotionEffectEvent;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Implements;
|
|
||||||
import org.spongepowered.asm.mixin.Interface;
|
|
||||||
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;
|
|
||||||
import io.izzel.arclight.common.bridge.entity.projectile.ArrowEntityBridge;
|
import io.izzel.arclight.common.bridge.entity.projectile.ArrowEntityBridge;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.network.syncher.EntityDataAccessor;
|
import net.minecraft.network.syncher.EntityDataAccessor;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
@ -22,6 +11,17 @@ import net.minecraft.world.entity.projectile.Arrow;
|
||||||
import net.minecraft.world.item.alchemy.Potion;
|
import net.minecraft.world.item.alchemy.Potion;
|
||||||
import net.minecraft.world.item.alchemy.PotionUtils;
|
import net.minecraft.world.item.alchemy.PotionUtils;
|
||||||
import net.minecraft.world.item.alchemy.Potions;
|
import net.minecraft.world.item.alchemy.Potions;
|
||||||
|
import org.bukkit.event.entity.EntityPotionEffectEvent;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Implements;
|
||||||
|
import org.spongepowered.asm.mixin.Interface;
|
||||||
|
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;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Mixin(Arrow.class)
|
@Mixin(Arrow.class)
|
||||||
@Implements(@Interface(iface = ArrowEntityBridge.Hack.class, prefix = "hack$"))
|
@Implements(@Interface(iface = ArrowEntityBridge.Hack.class, prefix = "hack$"))
|
||||||
|
@ -33,7 +33,7 @@ public abstract class ArrowEntityMixin extends AbstractArrowMixin implements Arr
|
||||||
@Shadow private Potion potion;
|
@Shadow private Potion potion;
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
@Inject(method = "doPostHurtEffects", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;addEffect(Lnet/minecraft/world/effect/MobEffectInstance;)Z"))
|
@Inject(method = "doPostHurtEffects", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;addEffect(Lnet/minecraft/world/effect/MobEffectInstance;Lnet/minecraft/world/entity/Entity;)Z"))
|
||||||
private void arclight$arrowHit(LivingEntity living, CallbackInfo ci) {
|
private void arclight$arrowHit(LivingEntity living, CallbackInfo ci) {
|
||||||
((LivingEntityBridge) living).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.ARROW);
|
((LivingEntityBridge) living).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.ARROW);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
@Mixin(SpectralArrow.class)
|
@Mixin(SpectralArrow.class)
|
||||||
public abstract class SpectralArrowMixin extends AbstractArrowMixin {
|
public abstract class SpectralArrowMixin extends AbstractArrowMixin {
|
||||||
|
|
||||||
@Inject(method = "doPostHurtEffects", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;addEffect(Lnet/minecraft/world/effect/MobEffectInstance;)Z"))
|
@Inject(method = "doPostHurtEffects", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;addEffect(Lnet/minecraft/world/effect/MobEffectInstance;Lnet/minecraft/world/entity/Entity;)Z"))
|
||||||
private void arclight$hit(LivingEntity living, CallbackInfo ci) {
|
private void arclight$hit(LivingEntity living, CallbackInfo ci) {
|
||||||
((LivingEntityBridge) living).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.ARROW);
|
((LivingEntityBridge) living).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.ARROW);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.raid;
|
package io.izzel.arclight.common.mixin.core.world.entity.raid;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.effect.MobEffects;
|
||||||
|
import net.minecraft.world.entity.raid.Raid;
|
||||||
|
import net.minecraft.world.entity.raid.Raids;
|
||||||
|
import net.minecraft.world.level.dimension.DimensionType;
|
||||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
@ -10,12 +16,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.world.effect.MobEffects;
|
|
||||||
import net.minecraft.world.entity.raid.Raid;
|
|
||||||
import net.minecraft.world.entity.raid.Raids;
|
|
||||||
import net.minecraft.world.level.dimension.DimensionType;
|
|
||||||
|
|
||||||
@Mixin(Raids.class)
|
@Mixin(Raids.class)
|
||||||
public class RaidManagerMixin {
|
public class RaidManagerMixin {
|
|
@ -1,8 +1,14 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.raid;
|
package io.izzel.arclight.common.mixin.core.world.entity.raid;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.raid.RaidBridge;
|
import io.izzel.arclight.common.bridge.world.raid.RaidBridge;
|
||||||
|
import net.minecraft.advancements.critereon.LocationTrigger;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.raid.Raid;
|
||||||
|
import net.minecraft.world.entity.raid.Raider;
|
||||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
@ -23,12 +29,6 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import net.minecraft.advancements.critereon.LocationTrigger;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.world.entity.raid.Raid;
|
|
||||||
import net.minecraft.world.entity.raid.Raider;
|
|
||||||
|
|
||||||
@Mixin(Raid.class)
|
@Mixin(Raid.class)
|
||||||
public class RaidMixin implements RaidBridge {
|
public class RaidMixin implements RaidBridge {
|
|
@ -1,6 +1,7 @@
|
||||||
package io.izzel.arclight.common.mixin.core.util;
|
package io.izzel.arclight.common.mixin.core.world.food;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.entity.LivingEntityBridge;
|
import io.izzel.arclight.common.bridge.entity.LivingEntityBridge;
|
||||||
|
import io.izzel.arclight.common.bridge.entity.player.PlayerEntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.util.FoodStatsBridge;
|
import io.izzel.arclight.common.bridge.util.FoodStatsBridge;
|
||||||
import net.minecraft.network.protocol.game.ClientboundSetHealthPacket;
|
import net.minecraft.network.protocol.game.ClientboundSetHealthPacket;
|
||||||
|
@ -11,6 +12,7 @@ import net.minecraft.world.food.FoodProperties;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||||
|
import org.bukkit.event.entity.EntityExhaustionEvent;
|
||||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
@ -21,15 +23,19 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(FoodData.class)
|
@Mixin(FoodData.class)
|
||||||
public abstract class FoodStatsMixin implements FoodStatsBridge {
|
public abstract class FoodDataMixin implements FoodStatsBridge {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow public int foodLevel;
|
@Shadow public int foodLevel;
|
||||||
@Shadow public abstract void eat(int foodLevelIn, float foodSaturationModifier);
|
@Shadow public abstract void eat(int foodLevelIn, float foodSaturationModifier);
|
||||||
@Shadow public float saturationLevel;
|
@Shadow public float saturationLevel;
|
||||||
|
@Shadow private int lastFoodLevel;
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
private Player entityhuman;
|
private Player entityhuman;
|
||||||
|
public int saturatedRegenRate = 10;
|
||||||
|
public int unsaturatedRegenRate = 80;
|
||||||
|
public int starvationRate = 80;
|
||||||
|
|
||||||
public void arclight$constructor() {
|
public void arclight$constructor() {
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
|
@ -40,8 +46,12 @@ public abstract class FoodStatsMixin implements FoodStatsBridge {
|
||||||
this.entityhuman = playerEntity;
|
this.entityhuman = playerEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redirect(method = "eat", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/food/FoodData;eat(IF)V"))
|
@Redirect(method = "eat(Lnet/minecraft/world/item/Item;Lnet/minecraft/world/item/ItemStack;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/food/FoodData;eat(IF)V"))
|
||||||
public void arclight$foodLevelChange(FoodData foodStats, int foodLevelIn, float foodSaturationModifier, Item maybeFood, ItemStack stack) {
|
public void arclight$foodLevelChange(FoodData foodStats, int foodLevelIn, float foodSaturationModifier, Item maybeFood, ItemStack stack) {
|
||||||
|
if (entityhuman == null) {
|
||||||
|
foodStats.eat(foodLevelIn, foodSaturationModifier);
|
||||||
|
return;
|
||||||
|
}
|
||||||
FoodProperties food = maybeFood.getFoodProperties();
|
FoodProperties food = maybeFood.getFoodProperties();
|
||||||
int oldFoodLevel = this.foodLevel;
|
int oldFoodLevel = this.foodLevel;
|
||||||
FoodLevelChangeEvent event = CraftEventFactory.callFoodLevelChangeEvent(entityhuman, food.getNutrition() + oldFoodLevel, stack);
|
FoodLevelChangeEvent event = CraftEventFactory.callFoodLevelChangeEvent(entityhuman, food.getNutrition() + oldFoodLevel, stack);
|
||||||
|
@ -53,10 +63,15 @@ public abstract class FoodStatsMixin implements FoodStatsBridge {
|
||||||
|
|
||||||
@Inject(method = "tick", at = @At(value = "INVOKE_ASSIGN", remap = false, target = "Ljava/lang/Math;max(II)I"))
|
@Inject(method = "tick", at = @At(value = "INVOKE_ASSIGN", remap = false, target = "Ljava/lang/Math;max(II)I"))
|
||||||
public void arclight$foodLevelChange2(Player player, CallbackInfo ci) {
|
public void arclight$foodLevelChange2(Player player, CallbackInfo ci) {
|
||||||
FoodLevelChangeEvent event = CraftEventFactory.callFoodLevelChangeEvent(entityhuman, Math.max(this.foodLevel - 1, 0));
|
if (entityhuman == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FoodLevelChangeEvent event = CraftEventFactory.callFoodLevelChangeEvent(entityhuman, Math.max(this.lastFoodLevel - 1, 0));
|
||||||
|
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
this.foodLevel = event.getFoodLevel();
|
this.foodLevel = event.getFoodLevel();
|
||||||
|
} else {
|
||||||
|
this.foodLevel = this.lastFoodLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
((ServerPlayer) entityhuman).connection.send(new ClientboundSetHealthPacket(((ServerPlayerEntityBridge) entityhuman).bridge$getBukkitEntity().getScaledHealth(), this.foodLevel, this.saturationLevel));
|
((ServerPlayer) entityhuman).connection.send(new ClientboundSetHealthPacket(((ServerPlayerEntityBridge) entityhuman).bridge$getBukkitEntity().getScaledHealth(), this.foodLevel, this.saturationLevel));
|
||||||
|
@ -64,7 +79,11 @@ public abstract class FoodStatsMixin implements FoodStatsBridge {
|
||||||
|
|
||||||
@Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;heal(F)V"))
|
@Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;heal(F)V"))
|
||||||
public void arclight$heal(Player player, CallbackInfo ci) {
|
public void arclight$heal(Player player, CallbackInfo ci) {
|
||||||
|
if (entityhuman == null) {
|
||||||
|
entityhuman = player;
|
||||||
|
}
|
||||||
((LivingEntityBridge) player).bridge$pushHealReason(EntityRegainHealthEvent.RegainReason.SATIATED);
|
((LivingEntityBridge) player).bridge$pushHealReason(EntityRegainHealthEvent.RegainReason.SATIATED);
|
||||||
|
((PlayerEntityBridge) player).bridge$pushExhaustReason(EntityExhaustionEvent.ExhaustionReason.REGEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -1,18 +1,18 @@
|
||||||
package io.izzel.arclight.common.mixin.core.util;
|
package io.izzel.arclight.common.mixin.core.world.inventory;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.util.IWorldPosCallableBridge;
|
import io.izzel.arclight.common.bridge.util.IWorldPosCallableBridge;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.inventory.ContainerLevelAccess;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.world.inventory.ContainerLevelAccess;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
|
|
||||||
@Mixin(ContainerLevelAccess.class)
|
@Mixin(ContainerLevelAccess.class)
|
||||||
public interface IWorldPosCallableMixin extends IWorldPosCallableBridge {
|
public interface ContainerLevelAccessMixin extends IWorldPosCallableBridge {
|
||||||
|
|
||||||
default Level getWorld() {
|
default Level getWorld() {
|
||||||
return bridge$getWorld();
|
return bridge$getWorld();
|
|
@ -19,6 +19,6 @@ public class FurnaceResultSlotMixin {
|
||||||
|
|
||||||
@Redirect(method = "checkTakeAchievements(Lnet/minecraft/world/item/ItemStack;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;awardUsedRecipesAndPopExperience(Lnet/minecraft/server/level/ServerPlayer;)V"))
|
@Redirect(method = "checkTakeAchievements(Lnet/minecraft/world/item/ItemStack;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;awardUsedRecipesAndPopExperience(Lnet/minecraft/server/level/ServerPlayer;)V"))
|
||||||
public void arclight$furnaceDropExp(AbstractFurnaceBlockEntity furnace, ServerPlayer player, ItemStack stack) {
|
public void arclight$furnaceDropExp(AbstractFurnaceBlockEntity furnace, ServerPlayer player, ItemStack stack) {
|
||||||
((AbstractFurnaceTileEntityBridge) furnace).bridge$dropExp(player.level, player.position(), player, stack, this.removeCount);
|
((AbstractFurnaceTileEntityBridge) furnace).bridge$dropExp(player, stack, this.removeCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,7 @@ public abstract class BowItemMixin extends ProjectileWeaponItem {
|
||||||
*/
|
*/
|
||||||
@Overwrite
|
@Overwrite
|
||||||
public void releaseUsing(ItemStack stack, Level worldIn, LivingEntity entityLiving, int timeLeft) {
|
public void releaseUsing(ItemStack stack, Level worldIn, LivingEntity entityLiving, int timeLeft) {
|
||||||
if (entityLiving instanceof Player) {
|
if (entityLiving instanceof Player playerentity) {
|
||||||
Player playerentity = (Player) entityLiving;
|
|
||||||
boolean flag = playerentity.getAbilities().instabuild || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY_ARROWS, stack) > 0;
|
boolean flag = playerentity.getAbilities().instabuild || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY_ARROWS, stack) > 0;
|
||||||
ItemStack itemstack = playerentity.getProjectile(stack);
|
ItemStack itemstack = playerentity.getProjectile(stack);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world;
|
package io.izzel.arclight.common.mixin.core.world.level;
|
||||||
|
|
||||||
|
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.border.WorldBorderBridge;
|
import io.izzel.arclight.common.bridge.world.border.WorldBorderBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.server.ServerChunkProviderBridge;
|
import io.izzel.arclight.common.bridge.world.server.ServerChunkProviderBridge;
|
||||||
|
@ -23,18 +24,22 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.border.WorldBorder;
|
import net.minecraft.world.level.border.WorldBorder;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraft.world.level.dimension.DimensionType;
|
import net.minecraft.world.level.dimension.DimensionType;
|
||||||
|
import net.minecraft.world.level.gameevent.GameEvent;
|
||||||
import net.minecraft.world.level.storage.LevelData;
|
import net.minecraft.world.level.storage.LevelData;
|
||||||
import net.minecraft.world.level.storage.ServerLevelData;
|
import net.minecraft.world.level.storage.ServerLevelData;
|
||||||
import net.minecraft.world.level.storage.WritableLevelData;
|
import net.minecraft.world.level.storage.WritableLevelData;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.craftbukkit.v.CraftServer;
|
import org.bukkit.craftbukkit.v.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v.CraftWorld;
|
import org.bukkit.craftbukkit.v.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
||||||
import org.bukkit.craftbukkit.v.block.data.CraftBlockData;
|
import org.bukkit.craftbukkit.v.block.data.CraftBlockData;
|
||||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||||
import org.bukkit.craftbukkit.v.generator.CustomChunkGenerator;
|
import org.bukkit.craftbukkit.v.generator.CustomChunkGenerator;
|
||||||
|
import org.bukkit.craftbukkit.v.util.CraftNamespacedKey;
|
||||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
import org.bukkit.event.world.GenericGameEvent;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.spigotmc.SpigotWorldConfig;
|
import org.spigotmc.SpigotWorldConfig;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
@ -53,12 +58,11 @@ import java.util.Optional;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@Mixin(Level.class)
|
@Mixin(Level.class)
|
||||||
public abstract class WorldMixin implements WorldBridge, LevelWriter {
|
public abstract class LevelMixin implements WorldBridge, LevelWriter {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow @Nullable public BlockEntity getBlockEntity(BlockPos pos) { return null; }
|
@Shadow @Nullable public BlockEntity getBlockEntity(BlockPos pos) { return null; }
|
||||||
@Shadow public abstract BlockState getBlockState(BlockPos pos);
|
@Shadow public abstract BlockState getBlockState(BlockPos pos);
|
||||||
@Shadow public abstract void setBlockEntity(BlockPos pos, @Nullable BlockEntity tileEntityIn);
|
|
||||||
@Shadow public abstract WorldBorder getWorldBorder();
|
@Shadow public abstract WorldBorder getWorldBorder();
|
||||||
@Shadow @Final private WorldBorder worldBorder;
|
@Shadow @Final private WorldBorder worldBorder;
|
||||||
@Shadow public abstract long getDayTime();
|
@Shadow public abstract long getDayTime();
|
||||||
|
@ -84,6 +88,7 @@ public abstract class WorldMixin implements WorldBridge, LevelWriter {
|
||||||
public org.spigotmc.SpigotWorldConfig spigotConfig;
|
public org.spigotmc.SpigotWorldConfig spigotConfig;
|
||||||
@SuppressWarnings("unused") // Access transformed to public by ArclightMixinPlugin
|
@SuppressWarnings("unused") // Access transformed to public by ArclightMixinPlugin
|
||||||
private static BlockPos lastPhysicsProblem; // Spigot
|
private static BlockPos lastPhysicsProblem; // Spigot
|
||||||
|
public boolean preventPoiUpdated = false;
|
||||||
|
|
||||||
public void arclight$constructor(WritableLevelData worldInfo, ResourceKey<Level> dimension, final DimensionType dimensionType, Supplier<ProfilerFiller> profiler, boolean isRemote, boolean isDebug, long seed) {
|
public void arclight$constructor(WritableLevelData worldInfo, ResourceKey<Level> dimension, final DimensionType dimensionType, Supplier<ProfilerFiller> profiler, boolean isRemote, boolean isDebug, long seed) {
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
|
@ -100,14 +105,15 @@ public abstract class WorldMixin implements WorldBridge, LevelWriter {
|
||||||
private void arclight$init(WritableLevelData info, ResourceKey<Level> dimension, DimensionType dimType, Supplier<ProfilerFiller> profiler, boolean isRemote, boolean isDebug, long seed, CallbackInfo ci) {
|
private void arclight$init(WritableLevelData info, ResourceKey<Level> dimension, DimensionType dimType, Supplier<ProfilerFiller> profiler, boolean isRemote, boolean isDebug, long seed, CallbackInfo ci) {
|
||||||
this.spigotConfig = new SpigotWorldConfig(((ServerLevelData) info).getLevelName());
|
this.spigotConfig = new SpigotWorldConfig(((ServerLevelData) info).getLevelName());
|
||||||
((WorldBorderBridge) this.worldBorder).bridge$setWorld((Level) (Object) this);
|
((WorldBorderBridge) this.worldBorder).bridge$setWorld((Level) (Object) this);
|
||||||
this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns();
|
this.ticksPerAnimalSpawns = this.getCraftServer().getTicksPerAnimalSpawns();
|
||||||
this.ticksPerMonsterSpawns = this.getServer().getTicksPerMonsterSpawns();
|
this.ticksPerMonsterSpawns = this.getCraftServer().getTicksPerMonsterSpawns();
|
||||||
this.ticksPerWaterSpawns = this.getServer().getTicksPerWaterSpawns();
|
this.ticksPerWaterSpawns = this.getCraftServer().getTicksPerWaterSpawns();
|
||||||
this.ticksPerWaterAmbientSpawns = this.getServer().getTicksPerWaterAmbientSpawns();
|
this.ticksPerWaterAmbientSpawns = this.getCraftServer().getTicksPerWaterAmbientSpawns();
|
||||||
this.ticksPerAmbientSpawns = this.getServer().getTicksPerAmbientSpawns();
|
this.ticksPerAmbientSpawns = this.getCraftServer().getTicksPerAmbientSpawns();
|
||||||
this.typeKey = this.getServer().getHandle().getServer().registryAccess().dimensionTypes().getResourceKey(dimensionType)
|
this.typeKey = this.getCraftServer().getHandle().getServer().registryAccess().registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY)
|
||||||
|
.getResourceKey(dimensionType)
|
||||||
.orElseGet(() -> {
|
.orElseGet(() -> {
|
||||||
Registry<DimensionType> registry = this.getServer().getHandle().getServer().registryAccess().dimensionTypes();
|
Registry<DimensionType> registry = this.getCraftServer().getHandle().getServer().registryAccess().registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY);
|
||||||
ResourceKey<DimensionType> typeRegistryKey = ResourceKey.create(registry.key(), dimension.location());
|
ResourceKey<DimensionType> typeRegistryKey = ResourceKey.create(registry.key(), dimension.location());
|
||||||
ArclightMod.LOGGER.warn("Assign {} to unknown dimension type {} as {}", typeRegistryKey, dimType);
|
ArclightMod.LOGGER.warn("Assign {} to unknown dimension type {} as {}", typeRegistryKey, dimType);
|
||||||
return typeRegistryKey;
|
return typeRegistryKey;
|
||||||
|
@ -171,7 +177,7 @@ public abstract class WorldMixin implements WorldBridge, LevelWriter {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "markAndNotifyBlock", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;updateNeighbours(Lnet/minecraft/world/level/LevelAccessor;Lnet/minecraft/core/BlockPos;II)V"))
|
@Inject(method = "markAndNotifyBlock", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;updateNeighbourShapes(Lnet/minecraft/world/level/LevelAccessor;Lnet/minecraft/core/BlockPos;II)V"))
|
||||||
private void arclight$callBlockPhysics(BlockPos pos, LevelChunk chunk, BlockState blockstate, BlockState state, int flags, int recursionLeft, CallbackInfo ci) {
|
private void arclight$callBlockPhysics(BlockPos pos, LevelChunk chunk, BlockState blockstate, BlockState state, int flags, int recursionLeft, CallbackInfo ci) {
|
||||||
try {
|
try {
|
||||||
if (this.world != null) {
|
if (this.world != null) {
|
||||||
|
@ -186,6 +192,13 @@ public abstract class WorldMixin implements WorldBridge, LevelWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject(method = "markAndNotifyBlock", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;onBlockStateChange(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;)V"))
|
||||||
|
private void arclight$preventPoiUpdate(BlockPos p_46605_, LevelChunk levelchunk, BlockState blockstate, BlockState p_46606_, int p_46607_, int p_46608_, CallbackInfo ci) {
|
||||||
|
if (this.preventPoiUpdated) {
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(method = "neighborChanged", cancellable = true,
|
@Inject(method = "neighborChanged", cancellable = true,
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;neighborChanged(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;Lnet/minecraft/core/BlockPos;Z)V"),
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;neighborChanged(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;Lnet/minecraft/core/BlockPos;Z)V"),
|
||||||
locals = LocalCapture.CAPTURE_FAILHARD)
|
locals = LocalCapture.CAPTURE_FAILHARD)
|
||||||
|
@ -204,7 +217,16 @@ public abstract class WorldMixin implements WorldBridge, LevelWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CraftServer getServer() {
|
@Inject(method = "postGameEventInRadius", cancellable = true, at = @At("HEAD"))
|
||||||
|
private void arclight$gameEventEvent(Entity entity, GameEvent gameEvent, BlockPos pos, int i, CallbackInfo ci) {
|
||||||
|
GenericGameEvent event = new GenericGameEvent(org.bukkit.GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(Registry.GAME_EVENT.getKey(gameEvent))), new Location(this.getWorld(), pos.getX(),pos.getY(), pos.getZ()), (entity == null) ? null : ((EntityBridge) entity).bridge$getBukkitEntity(), i);
|
||||||
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
if (event.isCancelled()) {
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CraftServer getCraftServer() {
|
||||||
return (CraftServer) Bukkit.getServer();
|
return (CraftServer) Bukkit.getServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,9 +241,8 @@ public abstract class WorldMixin implements WorldBridge, LevelWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (generator == null) {
|
if (generator == null) {
|
||||||
generator = getServer().getGenerator(((ServerLevelData) this.getLevelData()).getLevelName());
|
generator = getCraftServer().getGenerator(((ServerLevelData) this.getLevelData()).getLevelName());
|
||||||
if (generator != null && (Object) this instanceof ServerLevel) {
|
if (generator != null && (Object) this instanceof ServerLevel serverWorld) {
|
||||||
ServerLevel serverWorld = (ServerLevel) (Object) this;
|
|
||||||
CustomChunkGenerator gen = new CustomChunkGenerator(serverWorld, serverWorld.getChunkSource().getGenerator(), generator);
|
CustomChunkGenerator gen = new CustomChunkGenerator(serverWorld, serverWorld.getChunkSource().getGenerator(), generator);
|
||||||
((ServerChunkProviderBridge) serverWorld.getChunkSource()).bridge$setChunkGenerator(gen);
|
((ServerChunkProviderBridge) serverWorld.getChunkSource()).bridge$setChunkGenerator(gen);
|
||||||
}
|
}
|
||||||
|
@ -230,7 +251,7 @@ public abstract class WorldMixin implements WorldBridge, LevelWriter {
|
||||||
environment = ArclightServer.getEnvironment(this.typeKey);
|
environment = ArclightServer.getEnvironment(this.typeKey);
|
||||||
}
|
}
|
||||||
this.world = new CraftWorld((ServerLevel) (Object) this, generator, environment);
|
this.world = new CraftWorld((ServerLevel) (Object) this, generator, environment);
|
||||||
getServer().addWorld(this.world);
|
getCraftServer().addWorld(this.world);
|
||||||
}
|
}
|
||||||
return this.world;
|
return this.world;
|
||||||
}
|
}
|
|
@ -12,7 +12,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
@Mixin(BeehiveBlock.class)
|
@Mixin(BeehiveBlock.class)
|
||||||
public class BeehiveBlockMixin {
|
public class BeehiveBlockMixin {
|
||||||
|
|
||||||
@Redirect(method = "angerNearbyBees", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/Bee;setAttackTarget(Lnet/minecraft/world/entity/LivingEntity;)V"))
|
@Redirect(method = "angerNearbyBees", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/Bee;setTarget(Lnet/minecraft/world/entity/LivingEntity;)V"))
|
||||||
private void arclight$targetReason(Bee beeEntity, LivingEntity livingEntity) {
|
private void arclight$targetReason(Bee beeEntity, LivingEntity livingEntity) {
|
||||||
((MobEntityBridge) beeEntity).bridge$pushGoalTargetReason(EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true);
|
((MobEntityBridge) beeEntity).bridge$pushGoalTargetReason(EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true);
|
||||||
beeEntity.setTarget(livingEntity);
|
beeEntity.setTarget(livingEntity);
|
||||||
|
|
|
@ -24,8 +24,7 @@ public abstract class CommandBlockMixin {
|
||||||
public void neighborChanged(BlockState state, Level worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving) {
|
public void neighborChanged(BlockState state, Level worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving) {
|
||||||
if (!worldIn.isClientSide) {
|
if (!worldIn.isClientSide) {
|
||||||
BlockEntity tileentity = worldIn.getBlockEntity(pos);
|
BlockEntity tileentity = worldIn.getBlockEntity(pos);
|
||||||
if (tileentity instanceof CommandBlockEntity) {
|
if (tileentity instanceof CommandBlockEntity commandblocktileentity) {
|
||||||
CommandBlockEntity commandblocktileentity = (CommandBlockEntity) tileentity;
|
|
||||||
boolean flag = worldIn.hasNeighborSignal(pos);
|
boolean flag = worldIn.hasNeighborSignal(pos);
|
||||||
boolean flag1 = commandblocktileentity.isPowered();
|
boolean flag1 = commandblocktileentity.isPowered();
|
||||||
|
|
||||||
|
|
|
@ -1,31 +1,15 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
||||||
|
import io.izzel.arclight.common.bridge.item.crafting.IRecipeBridge;
|
||||||
import io.izzel.arclight.common.bridge.tileentity.AbstractFurnaceTileEntityBridge;
|
import io.izzel.arclight.common.bridge.tileentity.AbstractFurnaceTileEntityBridge;
|
||||||
|
import io.izzel.arclight.mixin.Eject;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||||
import org.bukkit.Bukkit;
|
import net.minecraft.core.BlockPos;
|
||||||
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
|
||||||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
|
||||||
import org.bukkit.craftbukkit.v.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.craftbukkit.v.util.CraftMagicNumbers;
|
|
||||||
import org.bukkit.entity.HumanEntity;
|
|
||||||
import org.bukkit.event.inventory.FurnaceBurnEvent;
|
|
||||||
import org.bukkit.event.inventory.FurnaceExtractEvent;
|
|
||||||
import org.bukkit.event.inventory.FurnaceSmeltEvent;
|
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
|
||||||
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.Redirect;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import net.minecraft.core.NonNullList;
|
import net.minecraft.core.NonNullList;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.WorldlyContainer;
|
import net.minecraft.world.WorldlyContainer;
|
||||||
import net.minecraft.world.entity.ExperienceOrb;
|
import net.minecraft.world.entity.ExperienceOrb;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
@ -35,50 +19,75 @@ import net.minecraft.world.item.crafting.Recipe;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
|
import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
||||||
|
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||||
|
import org.bukkit.craftbukkit.v.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.craftbukkit.v.util.CraftMagicNumbers;
|
||||||
|
import org.bukkit.entity.HumanEntity;
|
||||||
|
import org.bukkit.event.inventory.FurnaceBurnEvent;
|
||||||
|
import org.bukkit.event.inventory.FurnaceExtractEvent;
|
||||||
|
import org.bukkit.event.inventory.FurnaceSmeltEvent;
|
||||||
|
import org.bukkit.event.inventory.FurnaceStartSmeltEvent;
|
||||||
|
import org.bukkit.inventory.CookingRecipe;
|
||||||
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
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.Redirect;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Slice;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Mixin(AbstractFurnaceBlockEntity.class)
|
@Mixin(AbstractFurnaceBlockEntity.class)
|
||||||
public abstract class AbstractFurnaceTileEntityMixin extends LockableTileEntityMixin implements AbstractFurnaceTileEntityBridge {
|
public abstract class AbstractFurnaceBlockEntityMixin extends LockableBlockEntityMixin implements AbstractFurnaceTileEntityBridge {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow protected NonNullList<ItemStack> items;
|
@Shadow protected NonNullList<ItemStack> items;
|
||||||
@Shadow protected abstract int getBurnDuration(ItemStack stack);
|
@Shadow protected abstract int getBurnDuration(ItemStack stack);
|
||||||
@Shadow public int litTime;
|
|
||||||
@Shadow protected abstract boolean isLit();
|
@Shadow protected abstract boolean isLit();
|
||||||
@Shadow protected abstract boolean canBurn(@Nullable Recipe<?> recipeIn);
|
|
||||||
@Shadow public abstract void setRecipeUsed(@Nullable Recipe<?> recipe);
|
|
||||||
@Shadow public abstract List<Recipe<?>> getRecipesToAwardAndPopExperience(Level world, Vec3 pos);
|
|
||||||
@Shadow @Final private Object2IntOpenHashMap<ResourceLocation> recipesUsed;
|
@Shadow @Final private Object2IntOpenHashMap<ResourceLocation> recipesUsed;
|
||||||
|
@Shadow public abstract List<Recipe<?>> getRecipesToAwardAndPopExperience(ServerLevel p_154996_, Vec3 p_154997_);
|
||||||
|
@Shadow protected abstract boolean canBurn(@org.jetbrains.annotations.Nullable Recipe<?> p_155006_, NonNullList<ItemStack> p_155007_, int p_155008_);
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
public List<HumanEntity> transaction = new ArrayList<>();
|
public List<HumanEntity> transaction = new ArrayList<>();
|
||||||
private int maxStack = MAX_STACK;
|
private int maxStack = MAX_STACK;
|
||||||
|
|
||||||
private transient FurnaceBurnEvent arclight$burnEvent;
|
@Eject(method = "serverTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;isLit()Z"),
|
||||||
|
slice = @Slice(from = @At(value = "FIELD", target = "Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;litDuration:I"),
|
||||||
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;getBurnDuration(Lnet/minecraft/world/item/ItemStack;)I"))
|
to = @At(value = "INVOKE", remap = false, target = "Lnet/minecraft/world/item/ItemStack;hasContainerItem()Z")))
|
||||||
public void arclight$furnaceBurn(CallbackInfo ci) {
|
private static boolean arclight$setBurnTime(AbstractFurnaceBlockEntity furnace, CallbackInfo ci) {
|
||||||
ItemStack itemStack = this.items.get(1);
|
ItemStack itemStack = furnace.getItem(1);
|
||||||
CraftItemStack fuel = CraftItemStack.asCraftMirror(itemStack);
|
CraftItemStack fuel = CraftItemStack.asCraftMirror(itemStack);
|
||||||
|
FurnaceBurnEvent furnaceBurnEvent = new FurnaceBurnEvent(CraftBlock.at(furnace.level, furnace.getBlockPos()), fuel, ((AbstractFurnaceTileEntityBridge) furnace).bridge$getBurnDuration(itemStack));
|
||||||
|
Bukkit.getPluginManager().callEvent(furnaceBurnEvent);
|
||||||
|
|
||||||
arclight$burnEvent = new FurnaceBurnEvent(CraftBlock.at(this.level, this.worldPosition), fuel, getBurnDuration(itemStack));
|
if (furnaceBurnEvent.isCancelled()) {
|
||||||
Bukkit.getPluginManager().callEvent(arclight$burnEvent);
|
|
||||||
|
|
||||||
if (arclight$burnEvent.isCancelled()) {
|
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
arclight$burnEvent = null;
|
return false;
|
||||||
}
|
}
|
||||||
|
return ((AbstractFurnaceTileEntityBridge) furnace).bridge$isLit() && furnaceBurnEvent.isBurning();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redirect(method = "tick", at = @At(value = "INVOKE", ordinal = 4, target = "Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;isLit()Z"))
|
@Inject(method = "serverTick", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "FIELD", ordinal = 0, target = "Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;cookingProgress:I"))
|
||||||
public boolean arclight$setBurnTime(AbstractFurnaceBlockEntity furnace) {
|
private static void arclight$startSmelt(Level level, BlockPos pos, BlockState state, AbstractFurnaceBlockEntity furnace, CallbackInfo ci, Recipe<?> recipe) {
|
||||||
this.litTime = arclight$burnEvent.getBurnTime();
|
if (recipe != null && furnace.cookingProgress == 0) {
|
||||||
try {
|
CraftItemStack source = CraftItemStack.asCraftMirror(furnace.getItem(0));
|
||||||
return this.isLit() && arclight$burnEvent.isBurning();
|
CookingRecipe<?> cookingRecipe = (CookingRecipe<?>) ((IRecipeBridge) recipe).bridge$toBukkitRecipe();
|
||||||
} finally {
|
|
||||||
arclight$burnEvent = null;
|
FurnaceStartSmeltEvent event = new FurnaceStartSmeltEvent(CraftBlock.at(level, pos), source, cookingRecipe);
|
||||||
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
furnace.cookingTotalTime = event.getTotalCookTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,45 +96,42 @@ public abstract class AbstractFurnaceTileEntityMixin extends LockableTileEntityM
|
||||||
* @reason
|
* @reason
|
||||||
*/
|
*/
|
||||||
@Overwrite
|
@Overwrite
|
||||||
@SuppressWarnings("unchecked")
|
private boolean burn(@Nullable Recipe<?> recipe, NonNullList<ItemStack> items, int i) {
|
||||||
private void burn(@Nullable Recipe<?> recipe) {
|
if (recipe != null && this.canBurn(recipe, items, i)) {
|
||||||
if (recipe != null && this.canBurn(recipe)) {
|
ItemStack itemstack = items.get(0);
|
||||||
ItemStack itemstack = this.items.get(0);
|
ItemStack itemstack1 = ((Recipe<WorldlyContainer>) recipe).assemble((AbstractFurnaceBlockEntity) (Object) this);
|
||||||
ItemStack itemstack1 = ((Recipe<WorldlyContainer>) recipe).assemble((AbstractFurnaceBlockEntity)(Object)this);
|
ItemStack itemstack2 = items.get(2);
|
||||||
ItemStack itemstack2 = this.items.get(2);
|
|
||||||
|
|
||||||
CraftItemStack source = CraftItemStack.asCraftMirror(itemstack);
|
CraftItemStack source = CraftItemStack.asCraftMirror(itemstack);
|
||||||
org.bukkit.inventory.ItemStack result = CraftItemStack.asBukkitCopy(itemstack1);
|
org.bukkit.inventory.ItemStack result = CraftItemStack.asBukkitCopy(itemstack1);
|
||||||
|
|
||||||
FurnaceSmeltEvent event = new FurnaceSmeltEvent(CraftBlock.at(level, worldPosition), source, result);
|
FurnaceSmeltEvent furnaceSmeltEvent = new FurnaceSmeltEvent(CraftBlock.at(level, worldPosition), source, result);
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
Bukkit.getPluginManager().callEvent(furnaceSmeltEvent);
|
||||||
|
|
||||||
if (event.isCancelled()) {
|
if (furnaceSmeltEvent.isCancelled()) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = event.getResult();
|
result = furnaceSmeltEvent.getResult();
|
||||||
itemstack1 = CraftItemStack.asNMSCopy(result);
|
itemstack1 = CraftItemStack.asNMSCopy(result);
|
||||||
|
|
||||||
if (!itemstack1.isEmpty()) {
|
if (!itemstack1.isEmpty()) {
|
||||||
if (itemstack2.isEmpty()) {
|
if (itemstack2.isEmpty()) {
|
||||||
this.items.set(2, itemstack1.copy());
|
items.set(2, itemstack1.copy());
|
||||||
} else if (CraftItemStack.asCraftMirror(itemstack2).isSimilar(result)) {
|
} else if (CraftItemStack.asCraftMirror(itemstack2).isSimilar(result)) {
|
||||||
itemstack2.grow(itemstack1.getCount());
|
itemstack2.grow(itemstack1.getCount());
|
||||||
} else {
|
} else {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.level.isClientSide) {
|
if (itemstack.is(Blocks.WET_SPONGE.asItem()) && !items.get(1).isEmpty() && items.get(1).is(Items.BUCKET)) {
|
||||||
this.setRecipeUsed(recipe);
|
items.set(1, new ItemStack(Items.WATER_BUCKET));
|
||||||
}
|
|
||||||
|
|
||||||
if (itemstack.getItem() == Blocks.WET_SPONGE.asItem() && !this.items.get(1).isEmpty() && this.items.get(1).getItem() == Items.BUCKET) {
|
|
||||||
this.items.set(1, new ItemStack(Items.WATER_BUCKET));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
itemstack.shrink(1);
|
itemstack.shrink(1);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,13 +140,13 @@ public abstract class AbstractFurnaceTileEntityMixin extends LockableTileEntityM
|
||||||
private static ItemStack arclight$item;
|
private static ItemStack arclight$item;
|
||||||
private static int arclight$captureAmount;
|
private static int arclight$captureAmount;
|
||||||
|
|
||||||
public List<Recipe<?>> a(Level world, Vec3 pos, Player entity, ItemStack itemStack, int amount) {
|
public List<Recipe<?>> a(ServerLevel world, Vec3 vec, BlockPos pos, Player entity, ItemStack itemStack, int amount) {
|
||||||
try {
|
try {
|
||||||
arclight$item = itemStack;
|
arclight$item = itemStack;
|
||||||
arclight$captureAmount = amount;
|
arclight$captureAmount = amount;
|
||||||
arclight$captureFurnace = (AbstractFurnaceBlockEntity) (Object) this;
|
arclight$captureFurnace = (AbstractFurnaceBlockEntity) (Object) this;
|
||||||
arclight$capturePlayer = entity;
|
arclight$capturePlayer = entity;
|
||||||
List<Recipe<?>> list = this.getRecipesToAwardAndPopExperience(world, pos);
|
List<Recipe<?>> list = this.getRecipesToAwardAndPopExperience(world, vec);
|
||||||
entity.awardRecipes(list);
|
entity.awardRecipes(list);
|
||||||
this.recipesUsed.clear();
|
this.recipesUsed.clear();
|
||||||
return list;
|
return list;
|
||||||
|
@ -153,34 +159,19 @@ public abstract class AbstractFurnaceTileEntityMixin extends LockableTileEntityM
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Recipe<?>> bridge$dropExp(Level world, Vec3 pos, Player entity, ItemStack itemStack, int amount) {
|
public List<Recipe<?>> bridge$dropExp(ServerPlayer entity, ItemStack itemStack, int amount) {
|
||||||
return a(world, pos, entity, itemStack, amount);
|
return a(entity.getLevel(), entity.position(), this.worldPosition, entity, itemStack, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Redirect(method = "createExperience", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/ExperienceOrb;award(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/phys/Vec3;I)V"))
|
||||||
* @author IzzelAliz
|
private static void arclight$expEvent(ServerLevel level, Vec3 vec3, int amount) {
|
||||||
* @reason
|
|
||||||
*/
|
|
||||||
@Overwrite
|
|
||||||
private static void createExperience(Level world, Vec3 pos, int craftedAmount, float experience) {
|
|
||||||
int i = Mth.floor((float) craftedAmount * experience);
|
|
||||||
float f = Mth.frac((float) craftedAmount * experience);
|
|
||||||
if (f != 0.0F && Math.random() < (double) f) {
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arclight$capturePlayer != null && arclight$captureAmount != 0) {
|
if (arclight$capturePlayer != null && arclight$captureAmount != 0) {
|
||||||
FurnaceExtractEvent event = new FurnaceExtractEvent(((ServerPlayerEntityBridge) arclight$capturePlayer).bridge$getBukkitEntity(),
|
FurnaceExtractEvent event = new FurnaceExtractEvent(((ServerPlayerEntityBridge) arclight$capturePlayer).bridge$getBukkitEntity(),
|
||||||
CraftBlock.at(world, arclight$captureFurnace.getBlockPos()), CraftMagicNumbers.getMaterial(arclight$item.getItem()), arclight$captureAmount, i);
|
CraftBlock.at(level, arclight$captureFurnace.getBlockPos()), CraftMagicNumbers.getMaterial(arclight$item.getItem()), arclight$captureAmount, amount);
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
i = event.getExpToDrop();
|
amount = event.getExpToDrop();
|
||||||
}
|
|
||||||
|
|
||||||
while (i > 0) {
|
|
||||||
int j = ExperienceOrb.getExperienceValue(i);
|
|
||||||
i -= j;
|
|
||||||
world.addFreshEntity(new ExperienceOrb(world, pos.x, pos.y, pos.z, j));
|
|
||||||
}
|
}
|
||||||
|
ExperienceOrb.award(level, vec3, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -217,4 +208,14 @@ public abstract class AbstractFurnaceTileEntityMixin extends LockableTileEntityM
|
||||||
public void setMaxStackSize(int size) {
|
public void setMaxStackSize(int size) {
|
||||||
this.maxStack = size;
|
this.maxStack = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int bridge$getBurnDuration(ItemStack stack) {
|
||||||
|
return this.getBurnDuration(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean bridge$isLit() {
|
||||||
|
return this.isLit();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,10 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
|
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
|
||||||
|
import net.minecraft.core.NonNullList;
|
||||||
|
import net.minecraft.world.Container;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.block.entity.BarrelBlockEntity;
|
||||||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
@ -9,13 +13,9 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import net.minecraft.core.NonNullList;
|
|
||||||
import net.minecraft.world.Container;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.level.block.entity.BarrelBlockEntity;
|
|
||||||
|
|
||||||
@Mixin(BarrelBlockEntity.class)
|
@Mixin(BarrelBlockEntity.class)
|
||||||
public abstract class BarrelTileEntityMixin extends LockableTileEntityMixin implements IInventoryBridge, Container {
|
public abstract class BarrelBlockEntityMixin extends LockableBlockEntityMixin implements IInventoryBridge, Container {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow private NonNullList<ItemStack> items;
|
@Shadow private NonNullList<ItemStack> items;
|
|
@ -1,5 +1,10 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
|
import io.izzel.arclight.common.bridge.tileentity.BeaconTileEntityBridge;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.world.effect.MobEffect;
|
||||||
|
import net.minecraft.world.effect.MobEffectInstance;
|
||||||
|
import net.minecraft.world.level.block.entity.BeaconBlockEntity;
|
||||||
import org.bukkit.craftbukkit.v.potion.CraftPotionUtil;
|
import org.bukkit.craftbukkit.v.potion.CraftPotionUtil;
|
||||||
import org.bukkit.potion.PotionEffect;
|
import org.bukkit.potion.PotionEffect;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
@ -7,14 +12,8 @@ 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 io.izzel.arclight.common.bridge.tileentity.BeaconTileEntityBridge;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.world.effect.MobEffect;
|
|
||||||
import net.minecraft.world.effect.MobEffectInstance;
|
|
||||||
import net.minecraft.world.level.block.entity.BeaconBlockEntity;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
|
|
||||||
@Mixin(BeaconBlockEntity.class)
|
@Mixin(BeaconBlockEntity.class)
|
||||||
public abstract class BeaconTileEntityMixin implements BeaconTileEntityBridge {
|
public abstract class BeaconTileEntityMixin implements BeaconTileEntityBridge {
|
||||||
|
@ -26,7 +25,7 @@ public abstract class BeaconTileEntityMixin implements BeaconTileEntityBridge {
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
@Inject(method = "load", at = @At("RETURN"))
|
@Inject(method = "load", at = @At("RETURN"))
|
||||||
public void arclight$level(BlockState state, CompoundTag compound, CallbackInfo ci) {
|
public void arclight$level(CompoundTag compound, CallbackInfo ci) {
|
||||||
this.levels = compound.getInt("Levels");
|
this.levels = compound.getInt("Levels");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.entity.MobEntityBridge;
|
import io.izzel.arclight.common.bridge.entity.MobEntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.tags.EntityTypeTags;
|
import net.minecraft.tags.EntityTypeTags;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
|
@ -32,11 +33,12 @@ import javax.annotation.Nullable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Mixin(BeehiveBlockEntity.class)
|
@Mixin(BeehiveBlockEntity.class)
|
||||||
public abstract class BeehiveTileEntityMixin extends TileEntityMixin {
|
public abstract class BeehiveBlockEntityMixin extends BlockEntityMixin {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow @Final private List<BeehiveBlockEntity.BeeData> stored;
|
@Shadow @Final private List<BeehiveBlockEntity.BeeData> stored;
|
||||||
@Shadow protected abstract boolean releaseOccupant(BlockState p_235651_1_, BeehiveBlockEntity.BeeData p_235651_2_, @org.jetbrains.annotations.Nullable List<Entity> p_235651_3_, BeehiveBlockEntity.BeeReleaseStatus p_235651_4_);
|
@Shadow @Nullable public BlockPos savedFlowerPos;
|
||||||
|
@Shadow private static boolean releaseOccupant(Level p_155137_, BlockPos p_155138_, BlockState p_155139_, BeehiveBlockEntity.BeeData p_155140_, @org.jetbrains.annotations.Nullable List<Entity> p_155141_, BeehiveBlockEntity.BeeReleaseStatus p_155142_, @org.jetbrains.annotations.Nullable BlockPos p_155143_) { return false; }
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
public int maxBees = 3;
|
public int maxBees = 3;
|
||||||
|
@ -56,16 +58,21 @@ public abstract class BeehiveTileEntityMixin extends TileEntityMixin {
|
||||||
beeEntity.setTarget(livingEntity);
|
beeEntity.setTarget(livingEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Entity> tryReleaseBee(BlockState blockState, BeehiveBlockEntity.BeeReleaseStatus state, boolean force) {
|
public List<Entity> releaseBees(BlockState blockState, BeehiveBlockEntity.BeeReleaseStatus state, boolean force) {
|
||||||
List<Entity> list = Lists.newArrayList();
|
List<Entity> list = Lists.newArrayList();
|
||||||
this.stored.removeIf(bee -> this.releaseBee(blockState, bee, list, state, force));
|
this.stored.removeIf(bee -> releaseBee(level, worldPosition, blockState, bee, list, state, this.savedFlowerPos, force));
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Redirect(method = "addOccupantWithPresetTicks", at = @At(value = "INVOKE", remap = false, target = "Ljava/util/List;size()I"))
|
||||||
|
private int arclight$maxBee(List<?> list) {
|
||||||
|
return list.size() < this.maxBees ? 1 : 3;
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(method = "addOccupantWithPresetTicks(Lnet/minecraft/world/entity/Entity;ZI)V", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;stopRiding()V"))
|
@Inject(method = "addOccupantWithPresetTicks(Lnet/minecraft/world/entity/Entity;ZI)V", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;stopRiding()V"))
|
||||||
private void arclight$beeEnterBlock(Entity entity, boolean p_226962_2_, int p_226962_3_, CallbackInfo ci) {
|
private void arclight$beeEnterBlock(Entity entity, boolean p_226962_2_, int p_226962_3_, CallbackInfo ci) {
|
||||||
if (this.level != null) {
|
if (this.level != null) {
|
||||||
EntityEnterBlockEvent event = new EntityEnterBlockEvent(((EntityBridge) entity).bridge$getBukkitEntity(), CraftBlock.at(this.level, this.getPos()));
|
EntityEnterBlockEvent event = new EntityEnterBlockEvent(((EntityBridge) entity).bridge$getBukkitEntity(), CraftBlock.at(this.level, this.worldPosition));
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
if (event.isCancelled()) {
|
if (event.isCancelled()) {
|
||||||
if (entity instanceof Bee) {
|
if (entity instanceof Bee) {
|
||||||
|
@ -76,28 +83,28 @@ public abstract class BeehiveTileEntityMixin extends TileEntityMixin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean releaseBee(BlockState blockState, BeehiveBlockEntity.BeeData bee, @Nullable List<Entity> list, BeehiveBlockEntity.BeeReleaseStatus state, boolean force) {
|
private static boolean releaseBee(Level world, BlockPos pos, BlockState state, BeehiveBlockEntity.BeeData beeData, @Nullable List<Entity> list, BeehiveBlockEntity.BeeReleaseStatus status, @Nullable BlockPos pos1, boolean force) {
|
||||||
arclight$force = force;
|
arclight$force = force;
|
||||||
try {
|
try {
|
||||||
return this.releaseOccupant(blockState, bee, list, state);
|
return releaseOccupant(world, pos, state, beeData, list, status, pos1);
|
||||||
} finally {
|
} finally {
|
||||||
arclight$force = false;
|
arclight$force = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private transient boolean arclight$force;
|
private static transient boolean arclight$force;
|
||||||
|
|
||||||
@Redirect(method = "releaseOccupant", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;isNight()Z"))
|
@Redirect(method = "releaseOccupant", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;isNight()Z"))
|
||||||
private boolean arclight$bypassNightCheck(Level world) {
|
private static boolean arclight$bypassNightCheck(Level world) {
|
||||||
return !arclight$force && world.isNight();
|
return !arclight$force && world.isNight();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redirect(method = "releaseOccupant", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;getType()Lnet/minecraft/world/entity/EntityType;"))
|
@Redirect(method = "releaseOccupant", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;getType()Lnet/minecraft/world/entity/EntityType;"))
|
||||||
private EntityType<?> arclight$spawnFirst(Entity entity) {
|
private static EntityType<?> arclight$spawnFirst(Entity entity, Level level) {
|
||||||
EntityType<?> type = entity.getType();
|
EntityType<?> type = entity.getType();
|
||||||
if (type.is(EntityTypeTags.BEEHIVE_INHABITORS)) {
|
if (type.is(EntityTypeTags.BEEHIVE_INHABITORS)) {
|
||||||
((WorldBridge) this.level).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.BEEHIVE);
|
((WorldBridge) level).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.BEEHIVE);
|
||||||
if (!this.level.addFreshEntity(entity)) {
|
if (!level.addFreshEntity(entity)) {
|
||||||
return EntityType.ITEM_FRAME;
|
return EntityType.ITEM_FRAME;
|
||||||
} else {
|
} else {
|
||||||
return type;
|
return type;
|
||||||
|
@ -107,12 +114,12 @@ public abstract class BeehiveTileEntityMixin extends TileEntityMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redirect(method = "releaseOccupant", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
|
@Redirect(method = "releaseOccupant", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
|
||||||
private boolean arclight$addedBefore(Level world, Entity entityIn) {
|
private static boolean arclight$addedBefore(Level world, Entity entityIn) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "load", at = @At("RETURN"))
|
@Inject(method = "load", at = @At("RETURN"))
|
||||||
private void arclight$readMax(BlockState state, CompoundTag compound, CallbackInfo ci) {
|
private void arclight$readMax(CompoundTag compound, CallbackInfo ci) {
|
||||||
if (compound.contains("Bukkit.MaxEntities")) {
|
if (compound.contains("Bukkit.MaxEntities")) {
|
||||||
this.maxBees = compound.getInt("Bukkit.MaxEntities");
|
this.maxBees = compound.getInt("Bukkit.MaxEntities");
|
||||||
}
|
}
|
|
@ -1,11 +1,17 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.tileentity.TileEntityBridge;
|
import io.izzel.arclight.common.bridge.tileentity.TileEntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
||||||
import org.bukkit.craftbukkit.v.persistence.CraftPersistentDataContainer;
|
import org.bukkit.craftbukkit.v.persistence.CraftPersistentDataContainer;
|
||||||
import org.bukkit.craftbukkit.v.persistence.CraftPersistentDataTypeRegistry;
|
import org.bukkit.craftbukkit.v.persistence.CraftPersistentDataTypeRegistry;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
@ -14,29 +20,25 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
|
|
||||||
@Mixin(BlockEntity.class)
|
@Mixin(BlockEntity.class)
|
||||||
public abstract class TileEntityMixin implements TileEntityBridge {
|
public abstract class BlockEntityMixin implements TileEntityBridge {
|
||||||
|
|
||||||
private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry();
|
private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry();
|
||||||
public CraftPersistentDataContainer persistentDataContainer;
|
public CraftPersistentDataContainer persistentDataContainer;
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow @Nullable public Level level;
|
@Shadow @Nullable public Level level;
|
||||||
@Shadow protected BlockPos worldPosition;
|
@Shadow @Final protected BlockPos worldPosition;
|
||||||
@Shadow public abstract BlockState getBlockState();
|
@Shadow public abstract BlockState getBlockState();
|
||||||
@Shadow public abstract void setChanged();
|
@Shadow public abstract void setChanged();
|
||||||
@Shadow public BlockPos getBlockPos() { return null; }
|
@Shadow public BlockPos getBlockPos() { return null; }
|
||||||
@Shadow public abstract boolean onlyOpCanSetNbt();
|
@Shadow public abstract boolean onlyOpCanSetNbt();
|
||||||
|
@Shadow protected static void setChanged(Level p_155233_, BlockPos p_155234_, BlockState p_155235_) { }
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
@Inject(method = "load", at = @At("RETURN"))
|
@Inject(method = "load", at = @At("RETURN"))
|
||||||
public void arclight$loadPersistent(BlockState state, CompoundTag compound, CallbackInfo ci) {
|
public void arclight$loadPersistent(CompoundTag compound, CallbackInfo ci) {
|
||||||
this.persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY);
|
this.persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY);
|
||||||
|
|
||||||
CompoundTag persistentDataTag = compound.getCompound("PublicBukkitValues");
|
CompoundTag persistentDataTag = compound.getCompound("PublicBukkitValues");
|
|
@ -1,5 +1,14 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
|
import io.izzel.arclight.common.bridge.tileentity.TileEntityBridge;
|
||||||
|
import io.izzel.arclight.common.mod.util.ArclightCaptures;
|
||||||
|
import io.izzel.arclight.mixin.Eject;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.NonNullList;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.entity.BrewingStandBlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
||||||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||||
|
@ -13,62 +22,42 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
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.Redirect;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import net.minecraft.core.NonNullList;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.level.block.entity.BrewingStandBlockEntity;
|
|
||||||
|
|
||||||
@Mixin(BrewingStandBlockEntity.class)
|
@Mixin(BrewingStandBlockEntity.class)
|
||||||
public abstract class BrewingStandTileEntityMixin extends LockableTileEntityMixin {
|
public abstract class BrewingStandBlockEntityMixin extends LockableBlockEntityMixin {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow private NonNullList<ItemStack> items;
|
@Shadow private NonNullList<ItemStack> items;
|
||||||
@Shadow public int fuel;
|
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
public List<HumanEntity> transaction = new ArrayList<>();
|
public List<HumanEntity> transaction = new ArrayList<>();
|
||||||
private int maxStack = MAX_STACK;
|
private int maxStack = MAX_STACK;
|
||||||
|
|
||||||
private transient Integer arclight$fuel;
|
@Eject(method = "serverTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;shrink(I)V"))
|
||||||
private transient boolean arclight$consume;
|
private static void arclight$brewFuel(ItemStack stack, int count, CallbackInfo ci, Level level, BlockPos pos, BlockState state, BrewingStandBlockEntity entity) {
|
||||||
|
BrewingStandFuelEvent event = new BrewingStandFuelEvent(CraftBlock.at(level, pos), CraftItemStack.asCraftMirror(stack), 20);
|
||||||
@Inject(method = "tick", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,
|
|
||||||
at = @At(value = "FIELD", ordinal = 1, target = "Lnet/minecraft/world/level/block/entity/BrewingStandBlockEntity;fuel:I"))
|
|
||||||
public void arclight$brewFuel(CallbackInfo ci, ItemStack itemStack) {
|
|
||||||
BrewingStandFuelEvent event = new BrewingStandFuelEvent(CraftBlock.at(this.level, this.worldPosition), CraftItemStack.asCraftMirror(itemStack), 20);
|
|
||||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||||
|
|
||||||
if (event.isCancelled()) {
|
if (event.isCancelled()) {
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
arclight$fuel = null;
|
|
||||||
} else {
|
} else {
|
||||||
arclight$consume = event.isConsuming();
|
entity.fuel = event.getFuelPower();
|
||||||
arclight$fuel = event.getFuelPower();
|
if (entity.fuel > 0 && event.isConsuming()) {
|
||||||
}
|
stack.shrink(count);
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;shrink(I)V"))
|
|
||||||
public void arclight$brewFuel(ItemStack itemStack, int count) {
|
|
||||||
if (arclight$fuel != null) {
|
|
||||||
this.fuel = arclight$fuel;
|
|
||||||
if (arclight$fuel > 0 && arclight$consume) {
|
|
||||||
itemStack.shrink(count);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
arclight$fuel = null;
|
|
||||||
arclight$consume = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "doBrew", cancellable = true, at = @At("HEAD"))
|
@Inject(method = "doBrew", cancellable = true, at = @At("HEAD"))
|
||||||
public void arclight$brewPotion(CallbackInfo ci) {
|
private static void arclight$brewPotion(Level level, BlockPos pos, NonNullList<ItemStack> p_155293_, CallbackInfo ci) {
|
||||||
InventoryHolder owner = this.getOwner();
|
BrewingStandBlockEntity entity = ArclightCaptures.getTickingBlockEntity();
|
||||||
|
InventoryHolder owner = entity == null ? null : ((TileEntityBridge) entity).bridge$getOwner();
|
||||||
if (owner != null) {
|
if (owner != null) {
|
||||||
BrewEvent event = new BrewEvent(CraftBlock.at(level, worldPosition), (BrewerInventory) owner.getInventory(), this.fuel);
|
BrewEvent event = new BrewEvent(CraftBlock.at(level, pos), (BrewerInventory) owner.getInventory(), entity.fuel);
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
if (event.isCancelled()) {
|
if (event.isCancelled()) {
|
||||||
ci.cancel();
|
ci.cancel();
|
|
@ -0,0 +1,64 @@
|
||||||
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.Container;
|
||||||
|
import net.minecraft.world.Containers;
|
||||||
|
import net.minecraft.world.SimpleContainer;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeType;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.entity.CampfireBlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
||||||
|
import org.bukkit.craftbukkit.v.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.event.block.BlockCookEvent;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
|
||||||
|
@Mixin(CampfireBlockEntity.class)
|
||||||
|
public abstract class CampfireTileEntityMixin extends BlockEntityMixin {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author IzzelAliz
|
||||||
|
* @reason
|
||||||
|
*/
|
||||||
|
@Overwrite
|
||||||
|
public static void cookTick(Level level, BlockPos pos, BlockState state, CampfireBlockEntity entity) {
|
||||||
|
boolean flag = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < entity.getItems().size(); ++i) {
|
||||||
|
ItemStack itemstack = entity.getItems().get(i);
|
||||||
|
if (!itemstack.isEmpty()) {
|
||||||
|
flag = true;
|
||||||
|
if (entity.cookingProgress[i] >= entity.cookingTime[i]) {
|
||||||
|
Container container = new SimpleContainer(itemstack);
|
||||||
|
ItemStack itemstack1 = level.getRecipeManager().getRecipeFor(RecipeType.CAMPFIRE_COOKING, container, level).map((p_155305_) -> {
|
||||||
|
return p_155305_.assemble(container);
|
||||||
|
}).orElse(itemstack);
|
||||||
|
CraftItemStack source = CraftItemStack.asCraftMirror(itemstack);
|
||||||
|
org.bukkit.inventory.ItemStack result = CraftItemStack.asBukkitCopy(itemstack1);
|
||||||
|
|
||||||
|
BlockCookEvent blockCookEvent = new BlockCookEvent(CraftBlock.at(level, pos), source, result);
|
||||||
|
Bukkit.getPluginManager().callEvent(blockCookEvent);
|
||||||
|
|
||||||
|
if (blockCookEvent.isCancelled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = blockCookEvent.getResult();
|
||||||
|
itemstack1 = CraftItemStack.asNMSCopy(result);
|
||||||
|
|
||||||
|
Containers.dropItemStack(level, pos.getX(), pos.getY(), pos.getZ(), itemstack1);
|
||||||
|
entity.getItems().set(i, ItemStack.EMPTY);
|
||||||
|
level.sendBlockUpdated(pos, state, state, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag) {
|
||||||
|
setChanged(level, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
|
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
|
||||||
|
import net.minecraft.core.NonNullList;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
||||||
|
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||||
|
import org.bukkit.entity.HumanEntity;
|
||||||
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mixin(ChestBlockEntity.class)
|
||||||
|
public abstract class ChestBlockEntityMixin extends LockableBlockEntityMixin {
|
||||||
|
|
||||||
|
// @formatter:off
|
||||||
|
@Shadow private NonNullList<ItemStack> items;
|
||||||
|
// @formatter:on
|
||||||
|
|
||||||
|
public List<HumanEntity> transaction = new ArrayList<>();
|
||||||
|
private int maxStack = IInventoryBridge.MAX_STACK;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ItemStack> getContents() {
|
||||||
|
return this.items;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOpen(CraftHumanEntity who) {
|
||||||
|
transaction.add(who);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose(CraftHumanEntity who) {
|
||||||
|
transaction.remove(who);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<HumanEntity> getViewers() {
|
||||||
|
return transaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOwner(InventoryHolder owner) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxStackSize() {
|
||||||
|
if (maxStack == 0) maxStack = IInventoryBridge.MAX_STACK;
|
||||||
|
return maxStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxStackSize(int size) {
|
||||||
|
this.maxStack = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onlyOpCanSetNbt() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import io.izzel.arclight.common.bridge.command.CommandSourceBridge;
|
import io.izzel.arclight.common.bridge.command.CommandSourceBridge;
|
|
@ -1,4 +1,4 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.command.ICommandSourceBridge;
|
import io.izzel.arclight.common.bridge.command.ICommandSourceBridge;
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
|
@ -11,7 +11,7 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||||
@Mixin(targets = "net/minecraft/world/level/block/entity/CommandBlockEntity$1")
|
@Mixin(targets = "net/minecraft/world/level/block/entity/CommandBlockEntity$1")
|
||||||
public class CommandBlockTileEntity1Mixin implements ICommandSourceBridge {
|
public class CommandBlockTileEntity1Mixin implements ICommandSourceBridge {
|
||||||
|
|
||||||
@Shadow(aliases = {"this$0", "field_145767_a"}, remap = false) private CommandBlockEntity outerThis;
|
@Shadow(aliases = {"this$0", "f_59153_"}, remap = false) private CommandBlockEntity outerThis;
|
||||||
|
|
||||||
public CommandSender getBukkitSender(CommandSourceStack wrapper) {
|
public CommandSender getBukkitSender(CommandSourceStack wrapper) {
|
||||||
return new CraftBlockCommandSender(wrapper, outerThis);
|
return new CraftBlockCommandSender(wrapper, outerThis);
|
|
@ -1,6 +1,11 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.entity.player.PlayerEntityBridge;
|
import io.izzel.arclight.common.bridge.entity.player.PlayerEntityBridge;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.entity.ConduitBlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
||||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||||
import org.bukkit.event.entity.EntityPotionEffectEvent;
|
import org.bukkit.event.entity.EntityPotionEffectEvent;
|
||||||
|
@ -10,28 +15,23 @@ 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.LocalCapture;
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.level.block.entity.ConduitBlockEntity;
|
|
||||||
import net.minecraft.world.phys.AABB;
|
|
||||||
|
|
||||||
@Mixin(ConduitBlockEntity.class)
|
@Mixin(ConduitBlockEntity.class)
|
||||||
public abstract class ConduitTileEntityMixin extends TileEntityMixin {
|
public abstract class ConduitBlockEntityMixin extends BlockEntityMixin {
|
||||||
|
|
||||||
@Inject(method = "applyEffects", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;addEffect(Lnet/minecraft/world/effect/MobEffectInstance;)Z"))
|
@Inject(method = "applyEffects", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;addEffect(Lnet/minecraft/world/effect/MobEffectInstance;)Z"))
|
||||||
public void arclight$addEntity(CallbackInfo ci, int i, int j, int k, int l, int i1, AABB bb, List<?> list,
|
private static void arclight$addEntity(CallbackInfo ci, Player playerEntity) {
|
||||||
Iterator<?> iterator, Player playerEntity) {
|
|
||||||
((PlayerEntityBridge) playerEntity).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.CONDUIT);
|
((PlayerEntityBridge) playerEntity).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.CONDUIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "updateDestroyTarget", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;hurt(Lnet/minecraft/world/damagesource/DamageSource;F)Z"))
|
@Inject(method = "updateDestroyTarget", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;hurt(Lnet/minecraft/world/damagesource/DamageSource;F)Z"))
|
||||||
public void arclight$attackReason(CallbackInfo ci) {
|
private static void arclight$attackReason(Level level, BlockPos pos, BlockState p_155411_, List<BlockPos> p_155412_, ConduitBlockEntity p_155413_, CallbackInfo ci) {
|
||||||
CraftEventFactory.blockDamage = CraftBlock.at(this.level, this.worldPosition);
|
CraftEventFactory.blockDamage = CraftBlock.at(level, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "updateDestroyTarget", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/entity/LivingEntity;hurt(Lnet/minecraft/world/damagesource/DamageSource;F)Z"))
|
@Inject(method = "updateDestroyTarget", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/entity/LivingEntity;hurt(Lnet/minecraft/world/damagesource/DamageSource;F)Z"))
|
||||||
public void arclight$attackReasonReset(CallbackInfo ci) {
|
private static void arclight$attackReasonReset(CallbackInfo ci) {
|
||||||
CraftEventFactory.blockDamage = null;
|
CraftEventFactory.blockDamage = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,8 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
|
import net.minecraft.core.NonNullList;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.block.entity.DispenserBlockEntity;
|
||||||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
@ -8,12 +11,9 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import net.minecraft.core.NonNullList;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.level.block.entity.DispenserBlockEntity;
|
|
||||||
|
|
||||||
@Mixin(DispenserBlockEntity.class)
|
@Mixin(DispenserBlockEntity.class)
|
||||||
public abstract class DispenserTileEntityMixin extends LockableTileEntityMixin {
|
public abstract class DispenserBlockEntityMixin extends LockableBlockEntityMixin {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow private NonNullList<ItemStack> items;
|
@Shadow private NonNullList<ItemStack> items;
|
|
@ -1,4 +1,4 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.network.play.ServerPlayNetHandlerBridge;
|
import io.izzel.arclight.common.bridge.network.play.ServerPlayNetHandlerBridge;
|
||||||
|
@ -6,7 +6,9 @@ import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity;
|
import net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.craftbukkit.v.entity.CraftPlayer;
|
import org.bukkit.craftbukkit.v.entity.CraftPlayer;
|
||||||
|
@ -19,17 +21,17 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
@Mixin(TheEndGatewayBlockEntity.class)
|
@Mixin(TheEndGatewayBlockEntity.class)
|
||||||
public abstract class EndGatewayTileEntityMixin extends TileEntityMixin {
|
public abstract class EndGatewayBlockEntityMixin extends BlockEntityMixin {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow public abstract void triggerCooldown();
|
@Shadow private static void triggerCooldown(Level p_155850_, BlockPos p_155851_, BlockState p_155852_, TheEndGatewayBlockEntity p_155853_) { }
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
@Inject(method = "teleportEntity", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;teleportToWithTicket(DDD)V"))
|
@Inject(method = "teleportEntity", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;setPortalCooldown()V"))
|
||||||
public void arclight$portal(Entity entityIn, CallbackInfo ci, BlockPos pos) {
|
private static void arclight$portal(Level level, BlockPos pos, BlockState state, Entity entityIn, TheEndGatewayBlockEntity entity, CallbackInfo ci) {
|
||||||
if (entityIn instanceof ServerPlayer) {
|
if (entityIn instanceof ServerPlayer) {
|
||||||
CraftPlayer player = ((ServerPlayerEntityBridge) entityIn).bridge$getBukkitEntity();
|
CraftPlayer player = ((ServerPlayerEntityBridge) entityIn).bridge$getBukkitEntity();
|
||||||
Location location = new Location(((WorldBridge) level).bridge$getWorld(), pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D);
|
Location location = new Location(((WorldBridge) level).bridge$getWorld(), pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D);
|
||||||
location.setPitch(player.getLocation().getPitch());
|
location.setPitch(player.getLocation().getPitch());
|
||||||
location.setYaw(player.getLocation().getYaw());
|
location.setYaw(player.getLocation().getYaw());
|
||||||
|
|
||||||
|
@ -40,8 +42,9 @@ public abstract class EndGatewayTileEntityMixin extends TileEntityMixin {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entityIn.setPortalCooldown();
|
||||||
((ServerPlayNetHandlerBridge) (((ServerPlayer) entityIn)).connection).bridge$teleport(event.getTo());
|
((ServerPlayNetHandlerBridge) (((ServerPlayer) entityIn)).connection).bridge$teleport(event.getTo());
|
||||||
this.triggerCooldown(); // CraftBukkit - call at end of method
|
triggerCooldown(level, pos, state, entity);
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,21 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
|
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
|
||||||
|
import io.izzel.arclight.common.bridge.tileentity.TileEntityBridge;
|
||||||
|
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||||
|
import io.izzel.arclight.common.mod.util.ArclightCaptures;
|
||||||
|
import io.izzel.arclight.mixin.Eject;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.core.NonNullList;
|
||||||
|
import net.minecraft.world.CompoundContainer;
|
||||||
|
import net.minecraft.world.Container;
|
||||||
|
import net.minecraft.world.entity.item.ItemEntity;
|
||||||
|
import net.minecraft.world.entity.vehicle.MinecartHopper;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.entity.Hopper;
|
||||||
|
import net.minecraft.world.level.block.entity.HopperBlockEntity;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||||
import org.bukkit.craftbukkit.v.inventory.CraftInventoryDoubleChest;
|
import org.bukkit.craftbukkit.v.inventory.CraftInventoryDoubleChest;
|
||||||
|
@ -18,45 +32,24 @@ 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.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.core.NonNullList;
|
|
||||||
import net.minecraft.world.CompoundContainer;
|
|
||||||
import net.minecraft.world.Container;
|
|
||||||
import net.minecraft.world.entity.item.ItemEntity;
|
|
||||||
import net.minecraft.world.entity.vehicle.MinecartHopper;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.level.block.entity.Hopper;
|
|
||||||
import net.minecraft.world.level.block.entity.HopperBlockEntity;
|
|
||||||
|
|
||||||
@Mixin(HopperBlockEntity.class)
|
@Mixin(HopperBlockEntity.class)
|
||||||
public abstract class HopperTileEntityMixin extends LockableTileEntityMixin {
|
public abstract class HopperBlockEntityMixin extends LockableBlockEntityMixin {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow private NonNullList<ItemStack> items;
|
@Shadow private NonNullList<ItemStack> items;
|
||||||
@Shadow public abstract void setCooldown(int ticks);
|
|
||||||
@Shadow public abstract void setItem(int index, ItemStack stack);
|
@Shadow public abstract void setItem(int index, ItemStack stack);
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
public List<HumanEntity> transaction = new ArrayList<>();
|
public List<HumanEntity> transaction = new ArrayList<>();
|
||||||
private int maxStack = MAX_STACK;
|
private int maxStack = MAX_STACK;
|
||||||
|
|
||||||
private static transient boolean arclight$moveItem;
|
@Eject(method = "ejectItems", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/HopperBlockEntity;addItem(Lnet/minecraft/world/Container;Lnet/minecraft/world/Container;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/core/Direction;)Lnet/minecraft/world/item/ItemStack;"))
|
||||||
|
private static ItemStack arclight$moveItem(Container source, Container destination, ItemStack stack, Direction direction, CallbackInfoReturnable<Boolean> cir, Level level) {
|
||||||
@Inject(method = "ejectItems", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/level/block/entity/HopperBlockEntity;addItem(Lnet/minecraft/world/Container;Lnet/minecraft/world/Container;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/core/Direction;)Lnet/minecraft/world/item/ItemStack;"))
|
HopperBlockEntity entity = ArclightCaptures.getTickingBlockEntity();
|
||||||
public void arclight$returnIfMoveFail(CallbackInfoReturnable<Boolean> cir, Container inv, Direction direction, int i, ItemStack itemStack) {
|
|
||||||
if (arclight$moveItem) {
|
|
||||||
this.setItem(i, itemStack);
|
|
||||||
cir.setReturnValue(false);
|
|
||||||
}
|
|
||||||
arclight$moveItem = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(method = "ejectItems", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/HopperBlockEntity;addItem(Lnet/minecraft/world/Container;Lnet/minecraft/world/Container;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/core/Direction;)Lnet/minecraft/world/item/ItemStack;"))
|
|
||||||
public ItemStack arclight$moveItem(Container source, Container destination, ItemStack stack, Direction direction) {
|
|
||||||
CraftItemStack original = CraftItemStack.asCraftMirror(stack);
|
CraftItemStack original = CraftItemStack.asCraftMirror(stack);
|
||||||
|
|
||||||
Inventory destinationInventory;
|
Inventory destinationInventory;
|
||||||
|
@ -67,26 +60,19 @@ public abstract class HopperTileEntityMixin extends LockableTileEntityMixin {
|
||||||
destinationInventory = ((IInventoryBridge) destination).getOwnerInventory();
|
destinationInventory = ((IInventoryBridge) destination).getOwnerInventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
InventoryMoveItemEvent event = new InventoryMoveItemEvent(this.getOwner().getInventory(), original.clone(), destinationInventory, true);
|
InventoryMoveItemEvent event = new InventoryMoveItemEvent(((TileEntityBridge) entity).bridge$getOwner().getInventory(), original.clone(), destinationInventory, true);
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
if (arclight$moveItem = event.isCancelled()) {
|
if (event.isCancelled()) {
|
||||||
this.setCooldown(8); // Delay hopper checks
|
entity.setCooldown(((WorldBridge) level).bridge$spigotConfig().hopperTransfer); // Delay hopper checks
|
||||||
|
cir.setReturnValue(false);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return HopperBlockEntity.addItem(source, destination, CraftItemStack.asNMSCopy(event.getItem()), direction);
|
return HopperBlockEntity.addItem(source, destination, CraftItemStack.asNMSCopy(event.getItem()), direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "tryTakeInItemFromSlot", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/level/block/entity/HopperBlockEntity;addItem(Lnet/minecraft/world/Container;Lnet/minecraft/world/Container;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/core/Direction;)Lnet/minecraft/world/item/ItemStack;"))
|
|
||||||
private static void arclight$returnIfPullFail(Hopper hopper, Container inventoryIn, int index, Direction direction, CallbackInfoReturnable<Boolean> cir, ItemStack item, ItemStack item1) {
|
|
||||||
if (arclight$moveItem) {
|
|
||||||
inventoryIn.setItem(index, item1);
|
|
||||||
cir.setReturnValue(false);
|
|
||||||
}
|
|
||||||
arclight$moveItem = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(method = "tryTakeInItemFromSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/HopperBlockEntity;addItem(Lnet/minecraft/world/Container;Lnet/minecraft/world/Container;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/core/Direction;)Lnet/minecraft/world/item/ItemStack;"))
|
@Redirect(method = "tryTakeInItemFromSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/HopperBlockEntity;addItem(Lnet/minecraft/world/Container;Lnet/minecraft/world/Container;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/core/Direction;)Lnet/minecraft/world/item/ItemStack;"))
|
||||||
private static ItemStack arclight$pullItem(Container source, Container destination, ItemStack stack, Direction direction) {
|
private static ItemStack arclight$pullItem(Container source, Container destination, ItemStack stack, Direction direction, CallbackInfoReturnable<Boolean> cir, Hopper hopper, Container inv, int index) {
|
||||||
|
ItemStack origin = inv.getItem(index).copy();
|
||||||
CraftItemStack original = CraftItemStack.asCraftMirror(stack);
|
CraftItemStack original = CraftItemStack.asCraftMirror(stack);
|
||||||
|
|
||||||
Inventory sourceInventory;
|
Inventory sourceInventory;
|
||||||
|
@ -99,18 +85,20 @@ public abstract class HopperTileEntityMixin extends LockableTileEntityMixin {
|
||||||
|
|
||||||
InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, original.clone(), ((IInventoryBridge) destination).getOwnerInventory(), false);
|
InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, original.clone(), ((IInventoryBridge) destination).getOwnerInventory(), false);
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
if (arclight$moveItem = event.isCancelled()) {
|
if (event.isCancelled()) {
|
||||||
|
inv.setItem(index, origin);
|
||||||
if (destination instanceof HopperBlockEntity) {
|
if (destination instanceof HopperBlockEntity) {
|
||||||
((HopperBlockEntity) destination).setCooldown(8); // Delay hopper checks
|
((HopperBlockEntity) destination).setCooldown(8); // Delay hopper checks
|
||||||
} else if (destination instanceof MinecartHopper) {
|
} else if (destination instanceof MinecartHopper) {
|
||||||
((MinecartHopper) destination).setCooldown(4); // Delay hopper minecart checks
|
((MinecartHopper) destination).setCooldown(4); // Delay hopper minecart checks
|
||||||
}
|
}
|
||||||
|
cir.setReturnValue(false);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return HopperBlockEntity.addItem(source, destination, CraftItemStack.asNMSCopy(event.getItem()), direction);
|
return HopperBlockEntity.addItem(source, destination, CraftItemStack.asNMSCopy(event.getItem()), direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "addItem", cancellable = true, at = @At("HEAD"))
|
@Inject(method = "addItem(Lnet/minecraft/world/Container;Lnet/minecraft/world/entity/item/ItemEntity;)Z", cancellable = true, at = @At("HEAD"))
|
||||||
private static void arclight$pickupItem(Container inventory, ItemEntity itemEntity, CallbackInfoReturnable<Boolean> cir) {
|
private static void arclight$pickupItem(Container inventory, ItemEntity itemEntity, CallbackInfoReturnable<Boolean> cir) {
|
||||||
InventoryPickupItemEvent event = new InventoryPickupItemEvent(((IInventoryBridge) inventory).getOwnerInventory(), (Item) ((EntityBridge) itemEntity).bridge$getBukkitEntity());
|
InventoryPickupItemEvent event = new InventoryPickupItemEvent(((IInventoryBridge) inventory).getOwnerInventory(), (Item) ((EntityBridge) itemEntity).bridge$getBukkitEntity());
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
Bukkit.getPluginManager().callEvent(event);
|
|
@ -1,4 +1,4 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.command.ICommandSourceBridge;
|
import io.izzel.arclight.common.bridge.command.ICommandSourceBridge;
|
||||||
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
||||||
|
@ -33,7 +33,7 @@ import javax.annotation.Nullable;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Mixin(LecternBlockEntity.class)
|
@Mixin(LecternBlockEntity.class)
|
||||||
public abstract class LecternTileEntityMixin extends TileEntityMixin implements CommandSource, ICommandSourceBridge {
|
public abstract class LecternBlockEntityMixin extends BlockEntityMixin implements CommandSource, ICommandSourceBridge {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow @Final public Container bookAccess;
|
@Shadow @Final public Container bookAccess;
|
|
@ -1,28 +1,28 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
|
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
|
||||||
|
import io.izzel.arclight.common.bridge.tileentity.TileEntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||||
|
import net.minecraft.world.Container;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.crafting.Recipe;
|
||||||
|
import net.minecraft.world.level.block.LecternBlock;
|
||||||
|
import net.minecraft.world.level.block.entity.LecternBlockEntity;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import io.izzel.arclight.common.bridge.tileentity.TileEntityBridge;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import net.minecraft.world.Container;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.item.crafting.Recipe;
|
|
||||||
import net.minecraft.world.level.block.LecternBlock;
|
|
||||||
import net.minecraft.world.level.block.entity.LecternBlockEntity;
|
|
||||||
|
|
||||||
@Mixin(targets = "net/minecraft/world/level/block/entity/LecternBlockEntity$1")
|
@Mixin(targets = "net/minecraft/world/level/block/entity/LecternBlockEntity$1")
|
||||||
public abstract class LecternTileEntity1Mixin implements IInventoryBridge, Container {
|
public abstract class LecternTileEntity1Mixin implements IInventoryBridge, Container {
|
||||||
|
|
||||||
@Shadow(aliases = {"this$0", "field_214028_a"}, remap = false) private LecternBlockEntity outerThis;
|
@Shadow(aliases = {"this$0", "f_59572_"}, remap = false) private LecternBlockEntity outerThis;
|
||||||
|
|
||||||
public List<HumanEntity> transaction = new ArrayList<>();
|
public List<HumanEntity> transaction = new ArrayList<>();
|
||||||
private int maxStack = 1;
|
private int maxStack = 1;
|
|
@ -1,4 +1,4 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
|
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
|
||||||
import net.minecraft.world.Container;
|
import net.minecraft.world.Container;
|
||||||
|
@ -9,7 +9,7 @@ import org.bukkit.craftbukkit.v.block.CraftBlock;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
||||||
@Mixin(BaseContainerBlockEntity.class)
|
@Mixin(BaseContainerBlockEntity.class)
|
||||||
public abstract class LockableTileEntityMixin extends TileEntityMixin implements IInventoryBridge, Container {
|
public abstract class LockableBlockEntityMixin extends BlockEntityMixin implements IInventoryBridge, Container {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Location getLocation() {
|
public Location getLocation() {
|
|
@ -1,5 +1,9 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
|
import net.minecraft.core.NonNullList;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity;
|
||||||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
@ -11,13 +15,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import net.minecraft.core.NonNullList;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity;
|
|
||||||
|
|
||||||
@Mixin(ShulkerBoxBlockEntity.class)
|
@Mixin(ShulkerBoxBlockEntity.class)
|
||||||
public abstract class ShulkerBoxTileEntityMixin extends LockableTileEntityMixin {
|
public abstract class ShulkerBoxBlockEntityMixin extends LockableBlockEntityMixin {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow private NonNullList<ItemStack> itemStacks;
|
@Shadow private NonNullList<ItemStack> itemStacks;
|
|
@ -1,4 +1,4 @@
|
||||||
package io.izzel.arclight.common.mixin.core.tileentity;
|
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.command.ICommandSourceBridge;
|
import io.izzel.arclight.common.bridge.command.ICommandSourceBridge;
|
||||||
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
||||||
|
@ -9,7 +9,6 @@ import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.item.DyeColor;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.SignBlockEntity;
|
import net.minecraft.world.level.block.entity.SignBlockEntity;
|
||||||
import net.minecraft.world.phys.Vec2;
|
import net.minecraft.world.phys.Vec2;
|
||||||
|
@ -22,13 +21,13 @@ import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
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.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Mixin(SignBlockEntity.class)
|
@Mixin(SignBlockEntity.class)
|
||||||
public abstract class SignTileEntityMixin extends TileEntityMixin implements SignTileEntityBridge, CommandSource, ICommandSourceBridge {
|
public abstract class SignBlockEntityMixin extends BlockEntityMixin implements SignTileEntityBridge, CommandSource, ICommandSourceBridge {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Override @Accessor("isEditable") public abstract void bridge$setEditable(boolean editable);
|
@Override @Accessor("isEditable") public abstract void bridge$setEditable(boolean editable);
|
||||||
|
@ -39,10 +38,10 @@ public abstract class SignTileEntityMixin extends TileEntityMixin implements Sig
|
||||||
return new CommandSourceStack(this, vec3d, vec2f, world, i, s, component, server, entity);
|
return new CommandSourceStack(this, vec3d, vec2f, world, i, s, component, server, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "setColor", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;sendBlockUpdated(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;I)V"))
|
@Inject(method = "markUpdated", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;sendBlockUpdated(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;I)V"))
|
||||||
public void arclight$setColor(DyeColor newColor, CallbackInfoReturnable<Boolean> cir) {
|
public void arclight$setColor(CallbackInfo ci) {
|
||||||
if (this.level == null) {
|
if (this.level == null) {
|
||||||
cir.setReturnValue(true);
|
ci.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.border;
|
package io.izzel.arclight.common.mixin.core.world.level.border;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.world.border.WorldBorderBridge;
|
import io.izzel.arclight.common.bridge.world.border.WorldBorderBridge;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
|
@ -1,4 +1,4 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.biome;
|
package io.izzel.arclight.common.mixin.core.world.level.chunk;
|
||||||
|
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
@ -8,17 +8,21 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
@Mixin(ChunkBiomeContainer.class)
|
@Mixin(ChunkBiomeContainer.class)
|
||||||
public class BiomeContainerMixin {
|
public class ChunkBiomeContainerMixin {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow @Final private Biome[] biomes;
|
@Shadow @Final private Biome[] biomes;
|
||||||
@Shadow @Final private static int WIDTH_BITS;
|
@Shadow @Final private static int WIDTH_BITS;
|
||||||
|
@Shadow @Final private static int HORIZONTAL_MASK;
|
||||||
|
@Shadow @Final private int quartMinY;
|
||||||
|
@Shadow @Final private int quartHeight;
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
public void setBiome(int i, int j, int k, Biome biome) {
|
public void setBiome(int i, int j, int k, Biome biome) {
|
||||||
int l = i & ChunkBiomeContainer.HORIZONTAL_MASK;
|
int l = i & HORIZONTAL_MASK;
|
||||||
int i2 = Mth.clamp(j, 0, ChunkBiomeContainer.VERTICAL_MASK);
|
int i1 = Mth.clamp(j - this.quartMinY, 0, this.quartHeight);
|
||||||
int j2 = k & ChunkBiomeContainer.HORIZONTAL_MASK;
|
int j1 = k & HORIZONTAL_MASK;
|
||||||
this.biomes[i2 << WIDTH_BITS + WIDTH_BITS | j2 << WIDTH_BITS | l] = biome;
|
|
||||||
|
this.biomes[i1 << WIDTH_BITS + WIDTH_BITS | j1 << WIDTH_BITS | l] = biome;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,21 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.chunk;
|
package io.izzel.arclight.common.mixin.core.world.level.chunk;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.chunk.ChunkBridge;
|
import io.izzel.arclight.common.bridge.world.chunk.ChunkBridge;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.TickList;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkBiomeContainer;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
|
import net.minecraft.world.level.chunk.UpgradeData;
|
||||||
|
import net.minecraft.world.level.material.Fluid;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.craftbukkit.v.CraftChunk;
|
import org.bukkit.craftbukkit.v.CraftChunk;
|
||||||
import org.bukkit.craftbukkit.v.persistence.CraftPersistentDataContainer;
|
import org.bukkit.craftbukkit.v.persistence.CraftPersistentDataContainer;
|
||||||
|
@ -17,56 +31,45 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import net.minecraft.core.BlockPos;
|
import java.util.Map;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.util.ClassInstanceMultiMap;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.level.ChunkPos;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.TickList;
|
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.chunk.ChunkBiomeContainer;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
|
||||||
import net.minecraft.world.level.chunk.UpgradeData;
|
|
||||||
import net.minecraft.world.level.material.Fluid;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@Mixin(LevelChunk.class)
|
@Mixin(LevelChunk.class)
|
||||||
public abstract class ChunkMixin implements ChunkBridge {
|
public abstract class LevelChunkMixin implements ChunkBridge {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow @Nullable public abstract BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving);
|
@Shadow @Nullable public abstract BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving);
|
||||||
@Shadow @Final public Level level;
|
@Shadow @Final public Level level;
|
||||||
@Shadow @Final private ChunkPos chunkPos;
|
@Shadow @Final private ChunkPos chunkPos;
|
||||||
@Shadow private volatile boolean unsaved;
|
@Shadow private volatile boolean unsaved;
|
||||||
@Shadow private boolean lastSaveHadEntities;
|
@Shadow @Final private Map<BlockPos, CompoundTag> pendingBlockEntities;
|
||||||
@Shadow private long lastSaveTime;
|
|
||||||
@Shadow @Final public ClassInstanceMultiMap<Entity>[] entitySections;
|
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
public org.bukkit.Chunk bukkitChunk;
|
public org.bukkit.Chunk bukkitChunk;
|
||||||
public boolean mustNotSave;
|
public boolean mustNotSave;
|
||||||
public boolean needsDecoration;
|
public boolean needsDecoration;
|
||||||
private transient boolean arclight$doPlace;
|
private transient boolean arclight$doPlace;
|
||||||
public ServerLevel $$world;
|
public ServerLevel $$level;
|
||||||
|
|
||||||
private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry();
|
private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry();
|
||||||
public final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY);
|
public final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY);
|
||||||
|
|
||||||
@Inject(method = "<init>(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/level/ChunkPos;Lnet/minecraft/world/level/chunk/ChunkBiomeContainer;Lnet/minecraft/world/level/chunk/UpgradeData;Lnet/minecraft/world/level/TickList;Lnet/minecraft/world/level/TickList;J[Lnet/minecraft/world/level/chunk/LevelChunkSection;Ljava/util/function/Consumer;)V", at = @At("RETURN"))
|
@Inject(method = "<init>(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/level/ChunkPos;Lnet/minecraft/world/level/chunk/ChunkBiomeContainer;Lnet/minecraft/world/level/chunk/UpgradeData;Lnet/minecraft/world/level/TickList;Lnet/minecraft/world/level/TickList;J[Lnet/minecraft/world/level/chunk/LevelChunkSection;Ljava/util/function/Consumer;)V", at = @At("RETURN"))
|
||||||
private void arclight$init(Level worldIn, ChunkPos chunkPosIn, ChunkBiomeContainer biomeContainerIn, UpgradeData upgradeDataIn, TickList<Block> tickBlocksIn, TickList<Fluid> tickFluidsIn, long inhabitedTimeIn, LevelChunkSection[] sectionsIn, Consumer<LevelChunk> postLoadConsumerIn, CallbackInfo ci) {
|
private void arclight$init(Level worldIn, ChunkPos chunkPosIn, ChunkBiomeContainer biomeContainerIn, UpgradeData upgradeDataIn, TickList<Block> tickBlocksIn, TickList<Fluid> tickFluidsIn, long inhabitedTimeIn, LevelChunkSection[] sectionsIn, Consumer<LevelChunk> postLoadConsumerIn, CallbackInfo ci) {
|
||||||
this.$$world = ((ServerLevel) worldIn);
|
this.$$level = ((ServerLevel) worldIn);
|
||||||
bridge$setBukkitChunk(new CraftChunk((LevelChunk) (Object) this));
|
bridge$setBukkitChunk(new CraftChunk((LevelChunk) (Object) this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@Inject(method = "<init>(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/chunk/ProtoChunk;Ljava/util/function/Consumer;)V", at = @At("RETURN"))
|
||||||
public List<Entity>[] getEntitySlices() {
|
private void arclight$init(ServerLevel p_156365_, ProtoChunk p_156366_, Consumer<LevelChunk> p_156367_, CallbackInfo ci) {
|
||||||
return Arrays.stream(this.entitySections).map(ClassInstanceMultiMap::getAllInstances).toArray(List[]::new);
|
this.needsDecoration = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "removeBlockEntity", at = @At(value = "INVOKE_ASSIGN", remap = false, target = "Ljava/util/Map;remove(Ljava/lang/Object;)Ljava/lang/Object;"))
|
||||||
|
private void arclight$remove(BlockPos pos, CallbackInfo ci) {
|
||||||
|
if (!pendingBlockEntities.isEmpty()) {
|
||||||
|
pendingBlockEntities.remove(pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public org.bukkit.Chunk getBukkitChunk() {
|
public org.bukkit.Chunk getBukkitChunk() {
|
||||||
|
@ -169,12 +172,6 @@ public abstract class ChunkMixin implements ChunkBridge {
|
||||||
this.mustNotSave = !unloadEvent.isSaveChunk();
|
this.mustNotSave = !unloadEvent.isSaveChunk();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "<init>(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/level/chunk/ProtoChunk;)V",
|
|
||||||
at = @At("RETURN"))
|
|
||||||
public void arclight$setNeedsDecoration(Level worldIn, ProtoChunk primer, CallbackInfo ci) {
|
|
||||||
this.needsDecoration = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(method = "setBlockState", at = @At(value = "FIELD", ordinal = 1, target = "Lnet/minecraft/world/level/Level;isClientSide:Z"))
|
@Redirect(method = "setBlockState", at = @At(value = "FIELD", ordinal = 1, target = "Lnet/minecraft/world/level/Level;isClientSide:Z"))
|
||||||
public boolean arclight$redirectIsRemote(Level world) {
|
public boolean arclight$redirectIsRemote(Level world) {
|
||||||
return world.isClientSide && this.arclight$doPlace;
|
return world.isClientSide && this.arclight$doPlace;
|
||||||
|
@ -186,6 +183,6 @@ public abstract class ChunkMixin implements ChunkBridge {
|
||||||
*/
|
*/
|
||||||
@Overwrite
|
@Overwrite
|
||||||
public boolean isUnsaved() {
|
public boolean isUnsaved() {
|
||||||
return !this.mustNotSave && (this.unsaved || this.lastSaveHadEntities && this.level.getGameTime() != this.lastSaveTime);
|
return !this.mustNotSave && this.unsaved;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package io.izzel.arclight.common.mixin.core.world.level.chunk;
|
||||||
|
|
||||||
|
import io.izzel.arclight.common.mod.util.ArclightCaptures;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
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(targets = "net/minecraft/world/level/chunk/LevelChunk$BoundTickingBlockEntity")
|
||||||
|
public class LevelChunk_BoundTickingBlockEntityMixin<T extends BlockEntity> {
|
||||||
|
|
||||||
|
@Shadow @Final private T blockEntity;
|
||||||
|
|
||||||
|
@Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/BlockEntityTicker;tick(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/entity/BlockEntity;)V"))
|
||||||
|
private void arclight$captureBlockEntity(CallbackInfo ci) {
|
||||||
|
ArclightCaptures.captureTickingBlockEntity(this.blockEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "tick", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/level/block/entity/BlockEntityTicker;tick(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/entity/BlockEntity;)V"))
|
||||||
|
private void arclight$resetBlockEntity(CallbackInfo ci) {
|
||||||
|
ArclightCaptures.resetTickingBlockEntity();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,17 +1,17 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.chunk.storage;
|
package io.izzel.arclight.common.mixin.core.world.level.chunk.storage;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.chunk.storage.ChunkStorage;
|
import net.minecraft.world.level.chunk.storage.ChunkStorage;
|
||||||
import net.minecraft.world.level.dimension.DimensionType;
|
import net.minecraft.world.level.dimension.DimensionType;
|
||||||
import net.minecraft.world.level.levelgen.structure.LegacyStructureDataHandler;
|
import net.minecraft.world.level.levelgen.structure.LegacyStructureDataHandler;
|
||||||
import net.minecraft.world.level.storage.DimensionDataStorage;
|
import net.minecraft.world.level.storage.DimensionDataStorage;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Mixin(ChunkStorage.class)
|
@Mixin(ChunkStorage.class)
|
|
@ -1,6 +1,10 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.chunk.storage;
|
package io.izzel.arclight.common.mixin.core.world.level.chunk.storage;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.world.chunk.storage.RegionFileCacheBridge;
|
import io.izzel.arclight.common.bridge.world.chunk.storage.RegionFileCacheBridge;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.chunk.storage.RegionFile;
|
||||||
|
import net.minecraft.world.level.chunk.storage.RegionFileStorage;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
@ -11,10 +15,6 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.world.level.ChunkPos;
|
|
||||||
import net.minecraft.world.level.chunk.storage.RegionFile;
|
|
||||||
import net.minecraft.world.level.chunk.storage.RegionFileStorage;
|
|
||||||
|
|
||||||
@Mixin(RegionFileStorage.class)
|
@Mixin(RegionFileStorage.class)
|
||||||
public abstract class RegionFileCacheMixin implements RegionFileCacheBridge {
|
public abstract class RegionFileCacheMixin implements RegionFileCacheBridge {
|
|
@ -1,8 +1,15 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world;
|
package io.izzel.arclight.common.mixin.core.world.level.portal;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
import io.izzel.arclight.common.bridge.entity.EntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.TeleporterBridge;
|
import io.izzel.arclight.common.bridge.world.TeleporterBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||||
|
import net.minecraft.BlockUtil;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.portal.PortalForcer;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.craftbukkit.v.CraftWorld;
|
import org.bukkit.craftbukkit.v.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v.util.BlockStateListPopulator;
|
import org.bukkit.craftbukkit.v.util.BlockStateListPopulator;
|
||||||
|
@ -20,16 +27,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import net.minecraft.BlockUtil;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.portal.PortalForcer;
|
|
||||||
|
|
||||||
@Mixin(PortalForcer.class)
|
@Mixin(PortalForcer.class)
|
||||||
public abstract class TeleporterMixin implements TeleporterBridge {
|
public abstract class PortalForcerMixin implements TeleporterBridge {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow public abstract Optional<BlockUtil.FoundRectangle> createPortal(BlockPos pos, Direction.Axis axis);
|
@Shadow public abstract Optional<BlockUtil.FoundRectangle> createPortal(BlockPos pos, Direction.Axis axis);
|
||||||
|
@ -58,7 +58,7 @@ public abstract class TeleporterMixin implements TeleporterBridge {
|
||||||
return findPortal(pos, searchRadius);
|
return findPortal(pos, searchRadius);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ModifyArg(method = "makePortal", index = 1, at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/BlockPos;func_243514_a(Lnet/minecraft/util/math/BlockPos;ILnet/minecraft/util/Direction;Lnet/minecraft/util/Direction;)Ljava/lang/Iterable;"))
|
@ModifyArg(method = "createPortal", index = 1, at = @At(value = "INVOKE", target = "Lnet/minecraft/core/BlockPos;spiralAround(Lnet/minecraft/core/BlockPos;ILnet/minecraft/core/Direction;Lnet/minecraft/core/Direction;)Ljava/lang/Iterable;"))
|
||||||
private int arclight$changeRadius(int i) {
|
private int arclight$changeRadius(int i) {
|
||||||
return this.arclight$createRadius == -1 ? i : this.arclight$createRadius;
|
return this.arclight$createRadius == -1 ? i : this.arclight$createRadius;
|
||||||
}
|
}
|
|
@ -1,10 +1,15 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.storage;
|
package io.izzel.arclight.common.mixin.core.world.level.saveddata.maps;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.world.storage.MapDataBridge;
|
import io.izzel.arclight.common.bridge.world.storage.MapDataBridge;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.craftbukkit.v.CraftServer;
|
import org.bukkit.craftbukkit.v.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v.CraftWorld;
|
import org.bukkit.craftbukkit.v.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v.map.CraftMapView;
|
import org.bukkit.craftbukkit.v.map.CraftMapView;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
@ -13,40 +18,39 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.resources.ResourceKey;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
|
||||||
|
|
||||||
@Mixin(MapItemSavedData.class)
|
@Mixin(MapItemSavedData.class)
|
||||||
public abstract class MapDataMixin implements MapDataBridge {
|
public abstract class MapDataMixin implements MapDataBridge {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow public ResourceKey<Level> dimension;
|
@Shadow @Final public ResourceKey<Level> dimension;
|
||||||
|
@Shadow @Final private List<MapItemSavedData.HoldingPlayer> carriedBy;
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
public CraftMapView mapView;
|
public CraftMapView mapView;
|
||||||
private CraftServer server;
|
private CraftServer server;
|
||||||
private UUID uniqueId;
|
private UUID uniqueId;
|
||||||
|
public String id;
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At("RETURN"))
|
@Inject(method = "<init>", at = @At("RETURN"))
|
||||||
public void arclight$init(String mapname, CallbackInfo ci) {
|
public void arclight$init(int p_164768_, int p_164769_, byte p_164770_, boolean p_164771_, boolean p_164772_, boolean p_164773_, ResourceKey<Level> p_164774_, CallbackInfo ci) {
|
||||||
this.mapView = new CraftMapView((MapItemSavedData) (Object) this);
|
this.mapView = new CraftMapView((MapItemSavedData) (Object) this);
|
||||||
this.server = (CraftServer) Bukkit.getServer();
|
this.server = (CraftServer) Bukkit.getServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||||
@Redirect(method = "load", at = @At(value = "INVOKE", target = "Ljava/util/Optional;orElseThrow(Ljava/util/function/Supplier;)Ljava/lang/Object;"))
|
@Redirect(method = "load", at = @At(value = "INVOKE", target = "Ljava/util/Optional;orElseThrow(Ljava/util/function/Supplier;)Ljava/lang/Object;"))
|
||||||
public Object arclight$customDimension(Optional<ResourceKey<Level>> optional, Supplier<?> exceptionSupplier, CompoundTag nbt) {
|
private static Object arclight$customDimension(Optional<ResourceKey<Level>> optional, Supplier<?> exceptionSupplier, CompoundTag nbt) {
|
||||||
return optional.orElseGet(() -> {
|
return optional.orElseGet(() -> {
|
||||||
long least = nbt.getLong("UUIDLeast");
|
long least = nbt.getLong("UUIDLeast");
|
||||||
long most = nbt.getLong("UUIDMost");
|
long most = nbt.getLong("UUIDMost");
|
||||||
if (least != 0L && most != 0L) {
|
if (least != 0L && most != 0L) {
|
||||||
this.uniqueId = new UUID(most, least);
|
UUID uniqueId = new UUID(most, least);
|
||||||
CraftWorld world = (CraftWorld) this.server.getWorld(this.uniqueId);
|
CraftWorld world = (CraftWorld) Bukkit.getWorld(uniqueId);
|
||||||
if (world != null) {
|
if (world != null) {
|
||||||
return world.getHandle().dimension();
|
return world.getHandle().dimension();
|
||||||
}
|
}
|
||||||
|
@ -71,6 +75,16 @@ public abstract class MapDataMixin implements MapDataBridge {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bridge$setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<MapItemSavedData.HoldingPlayer> bridge$getCarriedBy() {
|
||||||
|
return this.carriedBy;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CraftMapView bridge$getMapView() {
|
public CraftMapView bridge$getMapView() {
|
||||||
return mapView;
|
return mapView;
|
|
@ -1,6 +1,12 @@
|
||||||
package io.izzel.arclight.common.mixin.core.world.storage;
|
package io.izzel.arclight.common.mixin.core.world.level.saveddata.maps;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
||||||
|
import io.izzel.arclight.common.bridge.world.storage.MapDataBridge;
|
||||||
|
import net.minecraft.network.protocol.Packet;
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundMapItemDataPacket;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.level.saveddata.maps.MapDecoration;
|
||||||
|
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
||||||
import org.bukkit.craftbukkit.v.map.RenderData;
|
import org.bukkit.craftbukkit.v.map.RenderData;
|
||||||
import org.bukkit.craftbukkit.v.util.CraftChatMessage;
|
import org.bukkit.craftbukkit.v.util.CraftChatMessage;
|
||||||
import org.bukkit.map.MapCursor;
|
import org.bukkit.map.MapCursor;
|
||||||
|
@ -8,21 +14,13 @@ import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import io.izzel.arclight.common.bridge.world.storage.MapDataBridge;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import net.minecraft.network.protocol.Packet;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundMapItemDataPacket;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.item.MapItem;
|
|
||||||
import net.minecraft.world.level.saveddata.maps.MapDecoration;
|
|
||||||
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
@Mixin(MapItemSavedData.HoldingPlayer.class)
|
@Mixin(MapItemSavedData.HoldingPlayer.class)
|
||||||
public class MapData_MapInfoMixin {
|
public abstract class MapData_MapInfoMixin {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@SuppressWarnings("target") @Shadow(aliases = {"this$0", "field_176107_c"}, remap = false) private MapItemSavedData outerThis;
|
@SuppressWarnings("target") @Shadow(aliases = {"this$0", "field_176107_c"}, remap = false) private MapItemSavedData outerThis;
|
||||||
|
@ -33,6 +31,8 @@ public class MapData_MapInfoMixin {
|
||||||
@Shadow private int maxDirtyY;
|
@Shadow private int maxDirtyY;
|
||||||
@Shadow private int tick;
|
@Shadow private int tick;
|
||||||
@Shadow @Final public Player player;
|
@Shadow @Final public Player player;
|
||||||
|
@Shadow private boolean dirtyDecorations;
|
||||||
|
@Shadow protected abstract MapItemSavedData.MapPatch createPatch();
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,20 +41,32 @@ public class MapData_MapInfoMixin {
|
||||||
*/
|
*/
|
||||||
@Overwrite
|
@Overwrite
|
||||||
@Nullable
|
@Nullable
|
||||||
public Packet<?> nextUpdatePacket(ItemStack stack) {
|
public Packet<?> nextUpdatePacket(int i) {
|
||||||
RenderData render = ((MapDataBridge) outerThis).bridge$getMapView().render(((ServerPlayerEntityBridge) this.player).bridge$getBukkitEntity()); // CraftBukkit
|
RenderData render = ((MapDataBridge) outerThis).bridge$getMapView().render(((ServerPlayerEntityBridge) this.player).bridge$getBukkitEntity()); // CraftBukkit
|
||||||
Collection<MapDecoration> icons = new ArrayList<>();
|
MapItemSavedData.MapPatch patch;
|
||||||
for (MapCursor cursor : render.cursors) {
|
|
||||||
if (cursor.isVisible()) {
|
|
||||||
icons.add(new MapDecoration(MapDecoration.Type.byIcon(cursor.getRawType()),
|
|
||||||
cursor.getX(), cursor.getY(), cursor.getDirection(), CraftChatMessage.fromStringOrNull(cursor.getCaption())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.dirtyData) {
|
if (this.dirtyData) {
|
||||||
this.dirtyData = false;
|
this.dirtyData = false;
|
||||||
return new ClientboundMapItemDataPacket(MapItem.getMapId(stack), outerThis.scale, outerThis.trackingPosition, outerThis.locked, icons, render.buffer, this.minDirtyX, this.minDirtyY, this.maxDirtyX + 1 - this.minDirtyX, this.maxDirtyY + 1 - this.minDirtyY);
|
var colors = outerThis.colors;
|
||||||
|
outerThis.colors = render.buffer;
|
||||||
|
patch = this.createPatch();
|
||||||
|
outerThis.colors = colors;
|
||||||
} else {
|
} else {
|
||||||
return this.tick++ % 5 == 0 ? new ClientboundMapItemDataPacket(MapItem.getMapId(stack), outerThis.scale, outerThis.trackingPosition, outerThis.locked, icons, render.buffer, 0, 0, 0, 0) : null;
|
patch = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Collection<MapDecoration> icons;
|
||||||
|
if (this.tick++ % 5 == 0) {
|
||||||
|
this.dirtyDecorations = false;
|
||||||
|
icons = new ArrayList<>();
|
||||||
|
for (MapCursor cursor : render.cursors) {
|
||||||
|
if (cursor.isVisible()) {
|
||||||
|
icons.add(new MapDecoration(MapDecoration.Type.byIcon(cursor.getRawType()),
|
||||||
|
cursor.getX(), cursor.getY(), cursor.getDirection(), CraftChatMessage.fromStringOrNull(cursor.getCaption())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
icons = null;
|
||||||
|
}
|
||||||
|
return icons == null && patch == null ? null : new ClientboundMapItemDataPacket(i, outerThis.scale, outerThis.locked, icons, patch);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,10 +4,10 @@ import io.izzel.arclight.common.bridge.entity.MobEntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.server.ServerWorldBridge;
|
import io.izzel.arclight.common.bridge.world.server.ServerWorldBridge;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.ListTag;
|
import net.minecraft.nbt.ListTag;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.util.random.WeightedRandomList;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EntityType;
|
import net.minecraft.world.entity.EntityType;
|
||||||
import net.minecraft.world.entity.Mob;
|
import net.minecraft.world.entity.Mob;
|
||||||
|
@ -20,7 +20,6 @@ import net.minecraft.world.phys.AABB;
|
||||||
import net.minecraftforge.event.ForgeEventFactory;
|
import net.minecraftforge.event.ForgeEventFactory;
|
||||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
@ -28,30 +27,26 @@ 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 java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Mixin(BaseSpawner.class)
|
@Mixin(BaseSpawner.class)
|
||||||
public abstract class AbstractSpawnerMixin {
|
public abstract class AbstractSpawnerMixin {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Shadow public abstract Level getLevel();
|
@Shadow public WeightedRandomList<SpawnData> spawnPotentials;
|
||||||
@Shadow @Final public List<SpawnData> spawnPotentials;
|
|
||||||
@Shadow protected abstract boolean isNearPlayer();
|
|
||||||
@Shadow private double oSpin;
|
|
||||||
@Shadow private double spin;
|
|
||||||
@Shadow public abstract BlockPos getPos();
|
|
||||||
@Shadow public int spawnDelay;
|
@Shadow public int spawnDelay;
|
||||||
@Shadow protected abstract void delay();
|
|
||||||
@Shadow public int spawnCount;
|
@Shadow public int spawnCount;
|
||||||
@Shadow public SpawnData nextSpawnData;
|
@Shadow public SpawnData nextSpawnData;
|
||||||
@Shadow public int spawnRange;
|
@Shadow public int spawnRange;
|
||||||
@Shadow public int maxNearbyEntities;
|
@Shadow public int maxNearbyEntities;
|
||||||
|
@Shadow private static WeightedRandomList<SpawnData> EMPTY_POTENTIALS;
|
||||||
|
@Shadow protected abstract boolean isNearPlayer(Level p_151344_, BlockPos p_151345_);
|
||||||
|
@Shadow protected abstract void delay(Level p_151351_, BlockPos p_151352_);
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
@Inject(method = "setEntityId", at = @At("RETURN"))
|
@Inject(method = "setEntityId", at = @At("RETURN"))
|
||||||
public void arclight$clearMobs(EntityType<?> type, CallbackInfo ci) {
|
public void arclight$clearMobs(EntityType<?> type, CallbackInfo ci) {
|
||||||
this.spawnPotentials.clear();
|
this.spawnPotentials = EMPTY_POTENTIALS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,110 +54,87 @@ public abstract class AbstractSpawnerMixin {
|
||||||
* @reason
|
* @reason
|
||||||
*/
|
*/
|
||||||
@Overwrite
|
@Overwrite
|
||||||
public void tick() {
|
public void serverTick(ServerLevel level, BlockPos pos) {
|
||||||
if (!this.isNearPlayer()) {
|
if (this.isNearPlayer(level, pos)) {
|
||||||
this.oSpin = this.spin;
|
if (this.spawnDelay == -1) {
|
||||||
} else {
|
this.delay(level, pos);
|
||||||
Level world = this.getLevel();
|
}
|
||||||
BlockPos blockpos = this.getPos();
|
|
||||||
if (!(world instanceof ServerLevel)) {
|
|
||||||
double d3 = (double) blockpos.getX() + world.random.nextDouble();
|
|
||||||
double d4 = (double) blockpos.getY() + world.random.nextDouble();
|
|
||||||
double d5 = (double) blockpos.getZ() + world.random.nextDouble();
|
|
||||||
world.addParticle(ParticleTypes.SMOKE, d3, d4, d5, 0.0D, 0.0D, 0.0D);
|
|
||||||
world.addParticle(ParticleTypes.FLAME, d3, d4, d5, 0.0D, 0.0D, 0.0D);
|
|
||||||
if (this.spawnDelay > 0) {
|
|
||||||
--this.spawnDelay;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.oSpin = this.spin;
|
if (this.spawnDelay > 0) {
|
||||||
this.spin = (this.spin + (double) (1000.0F / ((float) this.spawnDelay + 200.0F))) % 360.0D;
|
--this.spawnDelay;
|
||||||
} else {
|
} else {
|
||||||
if (this.spawnDelay == -1) {
|
|
||||||
this.delay();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.spawnDelay > 0) {
|
|
||||||
--this.spawnDelay;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean flag = false;
|
boolean flag = false;
|
||||||
|
|
||||||
for (int i = 0; i < this.spawnCount; ++i) {
|
for (int i = 0; i < this.spawnCount; ++i) {
|
||||||
CompoundTag compoundnbt = this.nextSpawnData.getTag();
|
CompoundTag compoundtag = this.nextSpawnData.getTag();
|
||||||
Optional<EntityType<?>> optional = EntityType.by(compoundnbt);
|
Optional<EntityType<?>> optional = EntityType.by(compoundtag);
|
||||||
if (!optional.isPresent()) {
|
if (optional.isEmpty()) {
|
||||||
this.delay();
|
this.delay(level, pos);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ListTag listnbt = compoundnbt.getList("Pos", 6);
|
ListTag listtag = compoundtag.getList("Pos", 6);
|
||||||
int j = listnbt.size();
|
int j = listtag.size();
|
||||||
double d0 = j >= 1 ? listnbt.getDouble(0) : (double) blockpos.getX() + (world.random.nextDouble() - world.random.nextDouble()) * (double) this.spawnRange + 0.5D;
|
double d0 = j >= 1 ? listtag.getDouble(0) : (double) pos.getX() + (level.random.nextDouble() - level.random.nextDouble()) * (double) this.spawnRange + 0.5D;
|
||||||
double d1 = j >= 2 ? listnbt.getDouble(1) : (double) (blockpos.getY() + world.random.nextInt(3) - 1);
|
double d1 = j >= 2 ? listtag.getDouble(1) : (double) (pos.getY() + level.random.nextInt(3) - 1);
|
||||||
double d2 = j >= 3 ? listnbt.getDouble(2) : (double) blockpos.getZ() + (world.random.nextDouble() - world.random.nextDouble()) * (double) this.spawnRange + 0.5D;
|
double d2 = j >= 3 ? listtag.getDouble(2) : (double) pos.getZ() + (level.random.nextDouble() - level.random.nextDouble()) * (double) this.spawnRange + 0.5D;
|
||||||
if (world.noCollision(optional.get().getAABB(d0, d1, d2))) {
|
if (level.noCollision(optional.get().getAABB(d0, d1, d2)) && SpawnPlacements.checkSpawnRules(optional.get(), level, MobSpawnType.SPAWNER, new BlockPos(d0, d1, d2), level.getRandom())) {
|
||||||
ServerLevel serverworld = (ServerLevel) world;
|
Entity entity = EntityType.loadEntityRecursive(compoundtag, level, (p_151310_) -> {
|
||||||
if (SpawnPlacements.checkSpawnRules(optional.get(), serverworld, MobSpawnType.SPAWNER, new BlockPos(d0, d1, d2), world.getRandom())) {
|
p_151310_.moveTo(d0, d1, d2, p_151310_.getYRot(), p_151310_.getXRot());
|
||||||
Entity entity = EntityType.loadEntityRecursive(compoundnbt, world, (p_221408_6_) -> {
|
return p_151310_;
|
||||||
p_221408_6_.moveTo(d0, d1, d2, p_221408_6_.yRot, p_221408_6_.xRot);
|
});
|
||||||
return p_221408_6_;
|
if (entity == null) {
|
||||||
});
|
this.delay(level, pos);
|
||||||
if (entity == null) {
|
return;
|
||||||
this.delay();
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int k = world.getEntitiesOfClass(entity.getClass(), (new AABB(blockpos.getX(), blockpos.getY(), blockpos.getZ(), blockpos.getX() + 1, blockpos.getY() + 1, blockpos.getZ() + 1)).inflate(this.spawnRange)).size();
|
int k = level.getEntitiesOfClass(entity.getClass(), (new AABB(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)).inflate(this.spawnRange)).size();
|
||||||
if (k >= this.maxNearbyEntities) {
|
if (k >= this.maxNearbyEntities) {
|
||||||
this.delay();
|
this.delay(level, pos);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.moveTo(entity.getX(), entity.getY(), entity.getZ(), world.random.nextFloat() * 360.0F, 0.0F);
|
entity.moveTo(entity.getX(), entity.getY(), entity.getZ(), level.random.nextFloat() * 360.0F, 0.0F);
|
||||||
if (entity instanceof Mob) {
|
if (entity instanceof Mob mob) {
|
||||||
Mob mobentity = (Mob) entity;
|
if (!ForgeEventFactory.canEntitySpawnSpawner(mob, level, (float) entity.getX(), (float) entity.getY(), (float) entity.getZ(), (BaseSpawner) (Object) this)) {
|
||||||
if (!ForgeEventFactory.canEntitySpawnSpawner(mobentity, world, (float) entity.getX(), (float) entity.getY(), (float) entity.getZ(), (BaseSpawner) (Object) this)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.nextSpawnData.getTag().size() == 1 && this.nextSpawnData.getTag().contains("id", 8)) {
|
|
||||||
if (!ForgeEventFactory.doSpecialSpawn(mobentity, world, (float) entity.getX(), (float) entity.getY(), (float) entity.getZ(), (BaseSpawner) (Object) this, MobSpawnType.SPAWNER))
|
|
||||||
((Mob) entity).finalizeSpawn(serverworld, world.getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.SPAWNER, null, null);
|
|
||||||
}
|
|
||||||
if (((WorldBridge) mobentity.level).bridge$spigotConfig().nerfSpawnerMobs) {
|
|
||||||
((MobEntityBridge) mobentity).bridge$setAware(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CraftEventFactory.callSpawnerSpawnEvent(entity, blockpos).isCancelled()) {
|
|
||||||
Entity vehicle = entity.getVehicle();
|
|
||||||
if (vehicle != null) {
|
|
||||||
vehicle.remove();
|
|
||||||
}
|
|
||||||
for (Entity passenger : entity.getIndirectPassengers()) {
|
|
||||||
passenger.remove();
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!((ServerWorldBridge) serverworld).bridge$addAllEntitiesSafely(entity, CreatureSpawnEvent.SpawnReason.SPAWNER)) {
|
|
||||||
this.delay();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
world.levelEvent(2004, blockpos, 0);
|
if (this.nextSpawnData.getTag().size() == 1 && this.nextSpawnData.getTag().contains("id", 8)) {
|
||||||
if (entity instanceof Mob) {
|
if (!ForgeEventFactory.doSpecialSpawn(mob, level, (float) entity.getX(), (float) entity.getY(), (float) entity.getZ(), (BaseSpawner) (Object) this, MobSpawnType.SPAWNER))
|
||||||
((Mob) entity).spawnAnim();
|
((Mob) entity).finalizeSpawn(level, level.getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.SPAWNER, null, null);
|
||||||
|
}
|
||||||
|
if (((WorldBridge) mob.level).bridge$spigotConfig().nerfSpawnerMobs) {
|
||||||
|
((MobEntityBridge) mob).bridge$setAware(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
flag = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
|
||||||
|
Entity vehicle = entity.getVehicle();
|
||||||
|
if (vehicle != null) {
|
||||||
|
vehicle.discard();
|
||||||
|
}
|
||||||
|
for (Entity passenger : entity.getIndirectPassengers()) {
|
||||||
|
passenger.discard();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!((ServerWorldBridge) level).bridge$addAllEntitiesSafely(entity, CreatureSpawnEvent.SpawnReason.SPAWNER)) {
|
||||||
|
this.delay(level, pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
level.levelEvent(2004, pos, 0);
|
||||||
|
if (entity instanceof Mob) {
|
||||||
|
((Mob) entity).spawnAnim();
|
||||||
|
}
|
||||||
|
|
||||||
|
flag = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag) {
|
if (flag) {
|
||||||
this.delay();
|
this.delay(level, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,17 @@ package io.izzel.arclight.common.mixin.core.world.spawner;
|
||||||
import io.izzel.arclight.common.bridge.world.IWorldWriterBridge;
|
import io.izzel.arclight.common.bridge.world.IWorldWriterBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.spawner.WorldEntitySpawnerBridge;
|
import io.izzel.arclight.common.bridge.world.spawner.WorldEntitySpawnerBridge;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.entity.Mob;
|
||||||
|
import net.minecraft.world.entity.MobCategory;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.NaturalSpawner;
|
||||||
|
import net.minecraft.world.level.ServerLevelAccessor;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import net.minecraft.world.level.storage.LevelData;
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
@ -14,16 +25,6 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.world.entity.Mob;
|
|
||||||
import net.minecraft.world.entity.MobCategory;
|
|
||||||
import net.minecraft.world.level.NaturalSpawner;
|
|
||||||
import net.minecraft.world.level.ServerLevelAccessor;
|
|
||||||
import net.minecraft.world.level.biome.Biome;
|
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
|
||||||
import net.minecraft.world.level.storage.LevelData;
|
|
||||||
|
|
||||||
@Mixin(NaturalSpawner.class)
|
@Mixin(NaturalSpawner.class)
|
||||||
public abstract class WorldEntitySpawnerMixin {
|
public abstract class WorldEntitySpawnerMixin {
|
||||||
|
@ -61,30 +62,25 @@ public abstract class WorldEntitySpawnerMixin {
|
||||||
boolean spawnThisTick = true;
|
boolean spawnThisTick = true;
|
||||||
int limit = classification.getMaxInstancesPerChunk();
|
int limit = classification.getMaxInstancesPerChunk();
|
||||||
switch (classification) {
|
switch (classification) {
|
||||||
case MONSTER: {
|
case MONSTER -> {
|
||||||
spawnThisTick = spawnMonsterThisTick;
|
spawnThisTick = spawnMonsterThisTick;
|
||||||
limit = ((WorldBridge) world).bridge$getWorld().getMonsterSpawnLimit();
|
limit = ((WorldBridge) world).bridge$getWorld().getMonsterSpawnLimit();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case CREATURE: {
|
case CREATURE -> {
|
||||||
spawnThisTick = spawnAnimalThisTick;
|
spawnThisTick = spawnAnimalThisTick;
|
||||||
limit = ((WorldBridge) world).bridge$getWorld().getAnimalSpawnLimit();
|
limit = ((WorldBridge) world).bridge$getWorld().getAnimalSpawnLimit();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case WATER_CREATURE: {
|
case WATER_CREATURE -> {
|
||||||
spawnThisTick = spawnWaterThisTick;
|
spawnThisTick = spawnWaterThisTick;
|
||||||
limit = ((WorldBridge) world).bridge$getWorld().getWaterAnimalSpawnLimit();
|
limit = ((WorldBridge) world).bridge$getWorld().getWaterAnimalSpawnLimit();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case AMBIENT: {
|
case AMBIENT -> {
|
||||||
spawnThisTick = spawnAmbientThisTick;
|
spawnThisTick = spawnAmbientThisTick;
|
||||||
limit = ((WorldBridge) world).bridge$getWorld().getAmbientSpawnLimit();
|
limit = ((WorldBridge) world).bridge$getWorld().getAmbientSpawnLimit();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case WATER_AMBIENT: {
|
case WATER_AMBIENT -> {
|
||||||
spawnThisTick = spawnWaterAmbientThisTick;
|
spawnThisTick = spawnWaterAmbientThisTick;
|
||||||
limit = ((WorldBridge) world).bridge$getWorld().getWaterAmbientSpawnLimit();
|
limit = ((WorldBridge) world).bridge$getWorld().getWaterAmbientSpawnLimit();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (spawnThisTick) {
|
if (spawnThisTick) {
|
||||||
|
@ -99,13 +95,22 @@ public abstract class WorldEntitySpawnerMixin {
|
||||||
world.getProfiler().pop();
|
world.getProfiler().pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "spawnCategoryForPosition", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V"))
|
@Inject(method = "spawnCategoryForPosition(Lnet/minecraft/world/entity/MobCategory;Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/chunk/ChunkAccess;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/NaturalSpawner$SpawnPredicate;Lnet/minecraft/world/level/NaturalSpawner$AfterSpawnCallback;)V",
|
||||||
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V"))
|
||||||
private static void arclight$naturalSpawn(MobCategory p_234966_0_, ServerLevel worldIn, ChunkAccess p_234966_2_, BlockPos p_234966_3_, NaturalSpawner.SpawnPredicate p_234966_4_, NaturalSpawner.AfterSpawnCallback p_234966_5_, CallbackInfo ci) {
|
private static void arclight$naturalSpawn(MobCategory p_234966_0_, ServerLevel worldIn, ChunkAccess p_234966_2_, BlockPos p_234966_3_, NaturalSpawner.SpawnPredicate p_234966_4_, NaturalSpawner.AfterSpawnCallback p_234966_5_, CallbackInfo ci) {
|
||||||
((WorldBridge) worldIn).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.NATURAL);
|
((WorldBridge) worldIn).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.NATURAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Redirect(method = "spawnCategoryForPosition(Lnet/minecraft/world/entity/MobCategory;Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/chunk/ChunkAccess;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/NaturalSpawner$SpawnPredicate;Lnet/minecraft/world/level/NaturalSpawner$AfterSpawnCallback;)V",
|
||||||
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/NaturalSpawner$AfterSpawnCallback;run(Lnet/minecraft/world/entity/Mob;Lnet/minecraft/world/level/chunk/ChunkAccess;)V"))
|
||||||
|
private static void arclight$skipRun(NaturalSpawner.AfterSpawnCallback afterSpawnCallback, Mob mob, ChunkAccess chunkAccess) {
|
||||||
|
if (!mob.isRemoved()) {
|
||||||
|
afterSpawnCallback.run(mob, chunkAccess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(method = "spawnMobsForChunkGeneration", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/ServerLevelAccessor;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V"))
|
@Inject(method = "spawnMobsForChunkGeneration", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/ServerLevelAccessor;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V"))
|
||||||
private static void arclight$worldGenSpawn(ServerLevelAccessor worldIn, Biome biomeIn, int centerX, int centerZ, Random diameterX, CallbackInfo ci) {
|
private static void arclight$worldGenSpawn(ServerLevelAccessor accessor, Biome p_151618_, ChunkPos p_151619_, Random p_151620_, CallbackInfo ci) {
|
||||||
((IWorldWriterBridge) worldIn).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.CHUNK_GEN);
|
((IWorldWriterBridge) accessor).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.CHUNK_GEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,11 @@ package io.izzel.arclight.common.mixin.core.world.storage;
|
||||||
|
|
||||||
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.storage.PlayerDataBridge;
|
import io.izzel.arclight.common.bridge.world.storage.PlayerDataBridge;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.nbt.NbtIo;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.level.storage.PlayerDataStorage;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.bukkit.craftbukkit.v.entity.CraftPlayer;
|
import org.bukkit.craftbukkit.v.entity.CraftPlayer;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
@ -13,11 +18,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.nbt.NbtIo;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.level.storage.PlayerDataStorage;
|
|
||||||
|
|
||||||
@Mixin(PlayerDataStorage.class)
|
@Mixin(PlayerDataStorage.class)
|
||||||
public class PlayerDataMixin implements PlayerDataBridge {
|
public class PlayerDataMixin implements PlayerDataBridge {
|
||||||
|
@ -32,7 +32,7 @@ public class PlayerDataMixin implements PlayerDataBridge {
|
||||||
if (player instanceof ServerPlayer) {
|
if (player instanceof ServerPlayer) {
|
||||||
CraftPlayer craftPlayer = ((ServerPlayerEntityBridge) player).bridge$getBukkitEntity();
|
CraftPlayer craftPlayer = ((ServerPlayerEntityBridge) player).bridge$getBukkitEntity();
|
||||||
// Only update first played if it is older than the one we have
|
// Only update first played if it is older than the one we have
|
||||||
long modified = new File(this.playerDir, player.getUUID().toString() + ".dat").lastModified();
|
long modified = new File(this.playerDir, player.getUUID() + ".dat").lastModified();
|
||||||
if (modified < craftPlayer.getFirstPlayed()) {
|
if (modified < craftPlayer.getFirstPlayed()) {
|
||||||
craftPlayer.setFirstPlayed(modified);
|
craftPlayer.setFirstPlayed(modified);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ import net.minecraft.nbt.ListTag;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||||
import net.minecraft.world.level.storage.WorldData;
|
import net.minecraft.world.level.storage.WorldData;
|
||||||
import net.minecraftforge.fml.FMLWorldPersistenceHook;
|
|
||||||
import net.minecraftforge.fml.MavenVersionStringHelper;
|
|
||||||
import net.minecraftforge.fml.ModList;
|
import net.minecraftforge.fml.ModList;
|
||||||
|
import net.minecraftforge.fmllegacy.FMLWorldPersistenceHook;
|
||||||
|
import net.minecraftforge.fmllegacy.MavenVersionStringHelper;
|
||||||
import net.minecraftforge.registries.ForgeRegistry;
|
import net.minecraftforge.registries.ForgeRegistry;
|
||||||
import net.minecraftforge.registries.GameData;
|
import net.minecraftforge.registries.GameData;
|
||||||
import net.minecraftforge.registries.RegistryManager;
|
import net.minecraftforge.registries.RegistryManager;
|
||||||
|
|
|
@ -9,7 +9,7 @@ import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.Container;
|
import net.minecraft.world.Container;
|
||||||
import net.minecraft.world.MenuProvider;
|
import net.minecraft.world.MenuProvider;
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
import net.minecraftforge.fml.network.NetworkHooks;
|
import net.minecraftforge.fmllegacy.network.NetworkHooks;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
@ -40,7 +40,7 @@ public class NetworkHooksMixin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "sendMCRegistryPackets", remap = false, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/network/FMLMCRegisterPacketHandler;addChannels(Ljava/util/Set;Lnet/minecraft/network/NetworkManager;)V"))
|
@Inject(method = "sendMCRegistryPackets", remap = false, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fmllegacy/network/FMLMCRegisterPacketHandler;addChannels(Ljava/util/Set;Lnet/minecraft/network/Connection;)V"))
|
||||||
private static void arclight$withBukkitChannels(Connection manager, String direction, CallbackInfo ci, Set<ResourceLocation> resourceLocations) {
|
private static void arclight$withBukkitChannels(Connection manager, String direction, CallbackInfo ci, Set<ResourceLocation> resourceLocations) {
|
||||||
Bukkit.getMessenger().getIncomingChannels().stream().map(ResourceLocation::new).forEach(resourceLocations::add);
|
Bukkit.getMessenger().getIncomingChannels().stream().map(ResourceLocation::new).forEach(resourceLocations::add);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package io.izzel.arclight.common.mixin.forge;
|
||||||
|
|
||||||
import net.minecraft.network.protocol.Packet;
|
import net.minecraft.network.protocol.Packet;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraftforge.fml.network.PacketDistributor;
|
import net.minecraftforge.fmllegacy.network.PacketDistributor;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
|
||||||
|
|
|
@ -191,8 +191,7 @@ public class ArclightMixinPlugin implements IMixinConfigPlugin {
|
||||||
}
|
}
|
||||||
for (MethodNode method : classNode.methods) {
|
for (MethodNode method : classNode.methods) {
|
||||||
for (AbstractInsnNode instruction : method.instructions) {
|
for (AbstractInsnNode instruction : method.instructions) {
|
||||||
if (instruction instanceof FieldInsnNode) {
|
if (instruction instanceof FieldInsnNode node) {
|
||||||
FieldInsnNode node = (FieldInsnNode) instruction;
|
|
||||||
node.name = map.getOrDefault(node.name, node.name);
|
node.name = map.getOrDefault(node.name, node.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,8 +240,7 @@ public class ArclightMixinPlugin implements IMixinConfigPlugin {
|
||||||
private void remapCtor(ClassNode classNode, MethodNode methodNode) {
|
private void remapCtor(ClassNode classNode, MethodNode methodNode) {
|
||||||
boolean initialized = false;
|
boolean initialized = false;
|
||||||
for (AbstractInsnNode node : methodNode.instructions) {
|
for (AbstractInsnNode node : methodNode.instructions) {
|
||||||
if (node instanceof MethodInsnNode) {
|
if (node instanceof MethodInsnNode methodInsnNode) {
|
||||||
MethodInsnNode methodInsnNode = (MethodInsnNode) node;
|
|
||||||
if (methodInsnNode.name.equals("arclight$constructor")) {
|
if (methodInsnNode.name.equals("arclight$constructor")) {
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
throw new ClassFormatError("Duplicate constructor call");
|
throw new ClassFormatError("Duplicate constructor call");
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package io.izzel.arclight.common.mod.server.event;
|
package io.izzel.arclight.common.mod.server.event;
|
||||||
|
|
||||||
|
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
||||||
|
import io.izzel.arclight.common.mod.util.ArclightBlockSnapshot;
|
||||||
|
import io.izzel.arclight.common.mod.util.ArclightCaptures;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraftforge.common.util.BlockSnapshot;
|
import net.minecraftforge.common.util.BlockSnapshot;
|
||||||
|
@ -9,15 +11,12 @@ import net.minecraftforge.event.world.BlockEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.craftbukkit.v.CraftServer;
|
|
||||||
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
import org.bukkit.craftbukkit.v.block.CraftBlock;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.block.BlockMultiPlaceEvent;
|
import org.bukkit.event.block.BlockMultiPlaceEvent;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import io.izzel.arclight.common.mod.util.ArclightBlockSnapshot;
|
|
||||||
import io.izzel.arclight.common.mod.util.ArclightCaptures;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -27,9 +26,8 @@ public class BlockPlaceEventDispatcher {
|
||||||
@SubscribeEvent(receiveCanceled = true)
|
@SubscribeEvent(receiveCanceled = true)
|
||||||
public void onBlockPlace(BlockEvent.EntityPlaceEvent event) {
|
public void onBlockPlace(BlockEvent.EntityPlaceEvent event) {
|
||||||
Entity entity = event.getEntity();
|
Entity entity = event.getEntity();
|
||||||
if (entity instanceof ServerPlayer) {
|
if (entity instanceof ServerPlayerEntityBridge playerEntity) {
|
||||||
ServerPlayer playerEntity = (ServerPlayer) entity;
|
Player player = playerEntity.bridge$getBukkitEntity();
|
||||||
Player player = ((CraftServer) Bukkit.getServer()).getPlayer(playerEntity);
|
|
||||||
Direction direction = ArclightCaptures.getPlaceEventDirection();
|
Direction direction = ArclightCaptures.getPlaceEventDirection();
|
||||||
if (direction != null) {
|
if (direction != null) {
|
||||||
InteractionHand hand = ArclightCaptures.getPlaceEventHand(InteractionHand.MAIN_HAND);
|
InteractionHand hand = ArclightCaptures.getPlaceEventHand(InteractionHand.MAIN_HAND);
|
||||||
|
@ -63,9 +61,8 @@ public class BlockPlaceEventDispatcher {
|
||||||
@SubscribeEvent(receiveCanceled = true)
|
@SubscribeEvent(receiveCanceled = true)
|
||||||
public void onMultiPlace(BlockEvent.EntityMultiPlaceEvent event) {
|
public void onMultiPlace(BlockEvent.EntityMultiPlaceEvent event) {
|
||||||
Entity entity = event.getEntity();
|
Entity entity = event.getEntity();
|
||||||
if (entity instanceof ServerPlayer) {
|
if (entity instanceof ServerPlayerEntityBridge playerEntity) {
|
||||||
ServerPlayer playerEntity = (ServerPlayer) entity;
|
Player player = playerEntity.bridge$getBukkitEntity();
|
||||||
Player player = ((CraftServer) Bukkit.getServer()).getPlayer(playerEntity);
|
|
||||||
Direction direction = ArclightCaptures.getPlaceEventDirection();
|
Direction direction = ArclightCaptures.getPlaceEventDirection();
|
||||||
if (direction != null) {
|
if (direction != null) {
|
||||||
InteractionHand hand = ArclightCaptures.getPlaceEventHand(InteractionHand.MAIN_HAND);
|
InteractionHand hand = ArclightCaptures.getPlaceEventHand(InteractionHand.MAIN_HAND);
|
||||||
|
|
|
@ -9,6 +9,7 @@ import net.minecraft.world.entity.item.ItemEntity;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
import net.minecraft.world.level.DataPackConfig;
|
import net.minecraft.world.level.DataPackConfig;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import org.bukkit.TreeType;
|
import org.bukkit.TreeType;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.craftbukkit.v.event.CraftPortalEvent;
|
import org.bukkit.craftbukkit.v.event.CraftPortalEvent;
|
||||||
|
@ -230,6 +231,21 @@ public class ArclightCaptures {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static transient BlockEntity tickingBlockEntity;
|
||||||
|
|
||||||
|
public static void captureTickingBlockEntity(BlockEntity entity) {
|
||||||
|
tickingBlockEntity = entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resetTickingBlockEntity() {
|
||||||
|
tickingBlockEntity = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T extends BlockEntity> T getTickingBlockEntity() {
|
||||||
|
return (T) tickingBlockEntity;
|
||||||
|
}
|
||||||
|
|
||||||
private static void recapture(String type) {
|
private static void recapture(String type) {
|
||||||
throw new IllegalStateException("Recapturing " + type);
|
throw new IllegalStateException("Recapturing " + type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ import java.net.JarURLConnection;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.SeekableByteChannel;
|
import java.nio.channels.SeekableByteChannel;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
@ -97,7 +96,7 @@ public abstract class ArclightClassCache implements AutoCloseable {
|
||||||
String store;
|
String store;
|
||||||
Path version = basePath.resolve(".version");
|
Path version = basePath.resolve(".version");
|
||||||
if (Files.exists(version)) {
|
if (Files.exists(version)) {
|
||||||
store = new String(Files.readAllBytes(version), StandardCharsets.UTF_8);
|
store = Files.readString(version);
|
||||||
} else {
|
} else {
|
||||||
store = null;
|
store = null;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +116,7 @@ public abstract class ArclightClassCache implements AutoCloseable {
|
||||||
Files.createDirectories(blob);
|
Files.createDirectories(blob);
|
||||||
}
|
}
|
||||||
if (obsolete) {
|
if (obsolete) {
|
||||||
Files.write(version, current.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE);
|
Files.writeString(version, current, StandardOpenOption.CREATE);
|
||||||
ArclightMod.LOGGER.info(MARKER, "Obsolete plugin class cache is cleared");
|
ArclightMod.LOGGER.info(MARKER, "Obsolete plugin class cache is cleared");
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -162,8 +162,7 @@ public class ArclightRedirectAdapter implements PluginTransformer {
|
||||||
private static void redirect(ClassNode classNode, ClassLoaderRemapper remapper) {
|
private static void redirect(ClassNode classNode, ClassLoaderRemapper remapper) {
|
||||||
for (MethodNode methodNode : classNode.methods) {
|
for (MethodNode methodNode : classNode.methods) {
|
||||||
for (AbstractInsnNode insnNode : methodNode.instructions) {
|
for (AbstractInsnNode insnNode : methodNode.instructions) {
|
||||||
if (insnNode instanceof MethodInsnNode) {
|
if (insnNode instanceof MethodInsnNode from) {
|
||||||
MethodInsnNode from = (MethodInsnNode) insnNode;
|
|
||||||
if (from.getOpcode() == Opcodes.INVOKESPECIAL
|
if (from.getOpcode() == Opcodes.INVOKESPECIAL
|
||||||
&& Objects.equals(from.owner, classNode.superName)
|
&& Objects.equals(from.owner, classNode.superName)
|
||||||
&& Objects.equals(from.name, methodNode.name)
|
&& Objects.equals(from.name, methodNode.name)
|
||||||
|
@ -176,8 +175,7 @@ public class ArclightRedirectAdapter implements PluginTransformer {
|
||||||
Object[] bsmArgs = invokeDynamic.bsmArgs;
|
Object[] bsmArgs = invokeDynamic.bsmArgs;
|
||||||
for (int i = 0; i < bsmArgs.length; i++) {
|
for (int i = 0; i < bsmArgs.length; i++) {
|
||||||
Object bsmArg = bsmArgs[i];
|
Object bsmArg = bsmArgs[i];
|
||||||
if (bsmArg instanceof Handle) {
|
if (bsmArg instanceof Handle handle) {
|
||||||
Handle handle = (Handle) bsmArg;
|
|
||||||
if (toOpcode(handle.getTag()) != -1) {
|
if (toOpcode(handle.getTag()) != -1) {
|
||||||
bsmArgs[i] = processHandle(handle, remapper);
|
bsmArgs[i] = processHandle(handle, remapper);
|
||||||
}
|
}
|
||||||
|
@ -389,29 +387,21 @@ public class ArclightRedirectAdapter implements PluginTransformer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int toOpcode(int handleType) {
|
private static int toOpcode(int handleType) {
|
||||||
switch (handleType) {
|
return switch (handleType) {
|
||||||
case Opcodes.H_INVOKEINTERFACE:
|
case Opcodes.H_INVOKEINTERFACE -> Opcodes.INVOKEINTERFACE;
|
||||||
return Opcodes.INVOKEINTERFACE;
|
case Opcodes.H_INVOKEVIRTUAL -> Opcodes.INVOKEVIRTUAL;
|
||||||
case Opcodes.H_INVOKEVIRTUAL:
|
case Opcodes.H_INVOKESTATIC -> Opcodes.INVOKESTATIC;
|
||||||
return Opcodes.INVOKEVIRTUAL;
|
default -> -1;
|
||||||
case Opcodes.H_INVOKESTATIC:
|
};
|
||||||
return Opcodes.INVOKESTATIC;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int toHandle(int opcode) {
|
private static int toHandle(int opcode) {
|
||||||
switch (opcode) {
|
return switch (opcode) {
|
||||||
case Opcodes.INVOKEINTERFACE:
|
case Opcodes.INVOKEINTERFACE -> Opcodes.H_INVOKEINTERFACE;
|
||||||
return Opcodes.H_INVOKEINTERFACE;
|
case Opcodes.INVOKESTATIC -> Opcodes.H_INVOKESTATIC;
|
||||||
case Opcodes.INVOKESTATIC:
|
case Opcodes.INVOKEVIRTUAL -> Opcodes.H_INVOKEVIRTUAL;
|
||||||
return Opcodes.H_INVOKESTATIC;
|
default -> -1;
|
||||||
case Opcodes.INVOKEVIRTUAL:
|
};
|
||||||
return Opcodes.H_INVOKEVIRTUAL;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static AbstractInsnNode loadInt(int i) {
|
static AbstractInsnNode loadInt(int i) {
|
||||||
|
|
|
@ -62,8 +62,7 @@ public class ClassLoaderAdapter implements PluginTransformer {
|
||||||
}
|
}
|
||||||
for (MethodNode methodNode : node.methods) {
|
for (MethodNode methodNode : node.methods) {
|
||||||
for (AbstractInsnNode insnNode : methodNode.instructions) {
|
for (AbstractInsnNode insnNode : methodNode.instructions) {
|
||||||
if (insnNode instanceof MethodInsnNode) {
|
if (insnNode instanceof MethodInsnNode methodInsnNode) {
|
||||||
MethodInsnNode methodInsnNode = (MethodInsnNode) insnNode;
|
|
||||||
if (methodInsnNode.getOpcode() == Opcodes.INVOKESPECIAL && methodNode.name.equals("<init>") && methodInsnNode.name.equals("<init>") && methodInsnNode.owner.equals(node.superName)) {
|
if (methodInsnNode.getOpcode() == Opcodes.INVOKESPECIAL && methodNode.name.equals("<init>") && methodInsnNode.name.equals("<init>") && methodInsnNode.owner.equals(node.superName)) {
|
||||||
methodInsnNode.owner = info.superName;
|
methodInsnNode.owner = info.superName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,113 +27,31 @@
|
||||||
"commands.synchronization.ArgumentTypesMixin",
|
"commands.synchronization.ArgumentTypesMixin",
|
||||||
"fluid.FlowingFluidMixin",
|
"fluid.FlowingFluidMixin",
|
||||||
"fluid.LavaFluidMixin",
|
"fluid.LavaFluidMixin",
|
||||||
"world.inventory.CraftingInventoryMixin",
|
|
||||||
"world.inventory.CraftResultInventoryMixin",
|
|
||||||
"world.CompoundContainerMixin",
|
|
||||||
"world.inventory.EnderChestInventoryMixin",
|
|
||||||
"world.ContainerMixin",
|
|
||||||
"world.SimpleContainerMixin",
|
|
||||||
"world.inventory.MerchantInventoryMixin",
|
|
||||||
"world.inventory.AbstractFurnaceContainerMixin",
|
|
||||||
"world.inventory.ItemCombinerMixin",
|
|
||||||
"world.inventory.BeaconContainerMixin",
|
|
||||||
"world.inventory.BrewingStandContainerMixin",
|
|
||||||
"world.inventory.CartographyContainer1Mixin",
|
|
||||||
"world.inventory.CartographyContainer2Mixin",
|
|
||||||
"world.inventory.CartographyContainerMixin",
|
|
||||||
"world.inventory.ChestContainerMixin",
|
|
||||||
"world.inventory.AbstractContainerMenuMixin",
|
|
||||||
"world.inventory.ContainerTypeMixin",
|
|
||||||
"world.inventory.DispenserContainerMixin",
|
|
||||||
"world.inventory.EnchantmentContainer1Mixin",
|
|
||||||
"world.inventory.EnchantmentContainerMixin",
|
|
||||||
"world.inventory.FurnaceResultSlotMixin",
|
|
||||||
"world.inventory.GrindstoneContainer1Mixin",
|
|
||||||
"world.inventory.GrindstoneContainerMixin",
|
|
||||||
"world.inventory.HopperContainerMixin",
|
|
||||||
"world.inventory.HorseInventoryContainerMixin",
|
|
||||||
"world.inventory.LecternContainerMixin",
|
|
||||||
"world.inventory.LoomContainer1Mixin",
|
|
||||||
"world.inventory.LoomContainer2Mixin",
|
|
||||||
"world.inventory.LoomContainerMixin",
|
|
||||||
"world.inventory.MerchantContainerMixin",
|
|
||||||
"world.inventory.PlayerContainerMixin",
|
|
||||||
"world.inventory.RepairContainerMixin",
|
|
||||||
"world.inventory.ShulkerBoxContainerMixin",
|
|
||||||
"world.inventory.SlotMixin",
|
|
||||||
"world.inventory.SmithingTableContainerMixin",
|
|
||||||
"world.inventory.StonecutterContainer1Mixin",
|
|
||||||
"world.inventory.StonecutterContainerMixin",
|
|
||||||
"world.inventory.CraftingMenuMixin",
|
|
||||||
"world.item.ArmorStandItemMixin",
|
|
||||||
"world.item.BlockItemMixin",
|
|
||||||
"world.item.BoatItemMixin",
|
|
||||||
"world.item.BowItemMixin",
|
|
||||||
"world.item.BucketItemMixin",
|
|
||||||
"world.item.ChorusFruitItemMixin",
|
|
||||||
"world.item.CrossbowItemMixin",
|
|
||||||
"world.item.DyeItemMixin",
|
|
||||||
"world.item.EggItemMixin",
|
|
||||||
"world.item.EnderCrystalItemMixin",
|
|
||||||
"world.item.EnderEyeItemMixin",
|
|
||||||
"world.item.EnderPearlItemMixin",
|
|
||||||
"world.item.MapItemMixin",
|
|
||||||
"world.item.FireChargeItemMixin",
|
|
||||||
"world.item.FishingRodItemMixin",
|
|
||||||
"world.item.FlintAndSteelItemMixin",
|
|
||||||
"world.item.HangingEntityItemMixin",
|
|
||||||
"world.item.ItemStackMixin",
|
|
||||||
"world.item.LeadItemMixin",
|
|
||||||
"world.item.MerchantOfferMixin",
|
|
||||||
"world.item.MilkBucketItemMixin",
|
|
||||||
"world.item.MinecartItemMixin",
|
|
||||||
"world.item.PotionItemMixin",
|
|
||||||
"world.item.ShearsItemMixin",
|
|
||||||
"world.item.SnowballItemMixin",
|
|
||||||
"world.item.SpawnEggItemMixin",
|
|
||||||
"world.item.TridentItemMixin",
|
|
||||||
"world.item.crafting.BlastingRecipeMixin",
|
|
||||||
"world.item.crafting.CampfireCookingRecipeMixin",
|
|
||||||
"world.item.crafting.FurnaceRecipeMixin",
|
|
||||||
"world.item.crafting.IngredientMixin",
|
|
||||||
"world.item.crafting.RecipeMixin",
|
|
||||||
"world.item.crafting.RecipeManagerMixin",
|
|
||||||
"world.item.crafting.ServerRecipeBookMixin",
|
|
||||||
"world.item.crafting.ShapedRecipeMixin",
|
|
||||||
"world.item.crafting.ShapelessRecipeMixin",
|
|
||||||
"world.item.crafting.SmithingRecipeMixin",
|
|
||||||
"world.item.crafting.SmokingRecipeMixin",
|
|
||||||
"world.item.crafting.CustomRecipeMixin",
|
|
||||||
"world.item.crafting.StonecuttingRecipeMixin",
|
|
||||||
"world.level.storage.loot.entries.LootEntry_SerializerMixin",
|
|
||||||
"world.level.storage.loot.parameters.LootParametersMixin",
|
|
||||||
"world.level.storage.loot.LootTableManagerMixin",
|
|
||||||
"world.level.storage.loot.LootTableMixin",
|
|
||||||
"world.level.storage.loot.predicates.RandomChanceWithLootingMixin",
|
|
||||||
"world.level.storage.loot.predicates.SurvivesExplosionMixin",
|
|
||||||
"world.level.storage.loot.functions.LootingEnchantBonusMixin",
|
|
||||||
"network.ConnectionMixin",
|
"network.ConnectionMixin",
|
||||||
"network.protocol.PacketThreadUtilMixin",
|
|
||||||
"network.SynchedEntityDataMixin",
|
|
||||||
"network.ServerHandshakeNetHandlerMixin",
|
"network.ServerHandshakeNetHandlerMixin",
|
||||||
"network.protocol.handshake.CHandshakePacketMixin",
|
|
||||||
"network.ServerLoginNetHandlerMixin",
|
"network.ServerLoginNetHandlerMixin",
|
||||||
"network.ServerPlayNetHandlerMixin",
|
"network.ServerPlayNetHandlerMixin",
|
||||||
|
"network.ServerStatusNetHandlerMixin",
|
||||||
|
"network.SynchedEntityDataMixin",
|
||||||
|
"network.chat.ComponentMixin",
|
||||||
|
"network.chat.StyleMixin",
|
||||||
|
"network.chat.TextColorMixin",
|
||||||
|
"network.protocol.PacketThreadUtilMixin",
|
||||||
"network.protocol.game.CChatMessagePacketMixin",
|
"network.protocol.game.CChatMessagePacketMixin",
|
||||||
"network.protocol.game.CCloseWindowPacketMixin",
|
"network.protocol.game.CCloseWindowPacketMixin",
|
||||||
"network.protocol.game.CPlayerTryUseItemOnBlockPacketMixin",
|
"network.protocol.game.CPlayerTryUseItemOnBlockPacketMixin",
|
||||||
"network.protocol.game.CPlayerTryUseItemPacketMixin",
|
"network.protocol.game.CPlayerTryUseItemPacketMixin",
|
||||||
"network.protocol.game.SChatPacketMixin",
|
"network.protocol.game.SChatPacketMixin",
|
||||||
"network.protocol.game.SWorldBorderPacketMixin",
|
"network.protocol.game.SWorldBorderPacketMixin",
|
||||||
|
"network.protocol.handshake.CHandshakePacketMixin",
|
||||||
"network.rcon.RConConsoleSourceMixin",
|
"network.rcon.RConConsoleSourceMixin",
|
||||||
"network.ServerStatusNetHandlerMixin",
|
"server.BootstrapMixin",
|
||||||
"world.effect.MobEffectMixin",
|
|
||||||
"server.ServerScoreboardMixin",
|
|
||||||
"server.CustomServerBossInfoMixin",
|
"server.CustomServerBossInfoMixin",
|
||||||
"server.MainMixin",
|
"server.MainMixin",
|
||||||
"server.MinecraftServerMixin",
|
"server.MinecraftServerMixin",
|
||||||
"server.PlayerAdvancementsMixin",
|
"server.PlayerAdvancementsMixin",
|
||||||
"server.ServerFunctionManagerMixin",
|
"server.ServerFunctionManagerMixin",
|
||||||
|
"server.ServerScoreboardMixin",
|
||||||
"server.commands.EffectCommandMixin",
|
"server.commands.EffectCommandMixin",
|
||||||
"server.commands.GameRuleCommandMixin",
|
"server.commands.GameRuleCommandMixin",
|
||||||
"server.commands.ReloadCommandMixin",
|
"server.commands.ReloadCommandMixin",
|
||||||
|
@ -141,61 +59,39 @@
|
||||||
"server.commands.TeleportCommandMixin",
|
"server.commands.TeleportCommandMixin",
|
||||||
"server.commands.TimeCommandMixin",
|
"server.commands.TimeCommandMixin",
|
||||||
"server.dedicated.DedicatedServerMixin",
|
"server.dedicated.DedicatedServerMixin",
|
||||||
|
"server.level.ChunkHolderMixin",
|
||||||
|
"server.level.ChunkMap_TrackedEntityMixin",
|
||||||
|
"server.level.ChunkMapMixin",
|
||||||
|
"server.level.ServerChunkCache_MainThreadExecutorMixin",
|
||||||
|
"server.level.ServerChunkCacheMixin",
|
||||||
|
"server.level.ServerEntityMixin",
|
||||||
|
"server.level.ServerLevel_EntityCallbacksMixin",
|
||||||
|
"server.level.ServerLevelMixin",
|
||||||
|
"server.level.TicketManagerMixin",
|
||||||
|
"server.level.TicketTypeMixin",
|
||||||
"server.management.BanEntryMixin",
|
"server.management.BanEntryMixin",
|
||||||
"server.management.ServerPlayerGameModeMixin",
|
|
||||||
"server.management.PlayerListMixin",
|
"server.management.PlayerListMixin",
|
||||||
|
"server.management.ServerPlayerGameModeMixin",
|
||||||
"server.management.UserListMixin",
|
"server.management.UserListMixin",
|
||||||
"world.level.block.state.properties.IntegerPropertyMixin",
|
|
||||||
"stats.StatisticsCounterMixin",
|
"stats.StatisticsCounterMixin",
|
||||||
"tileentity.AbstractFurnaceTileEntityMixin",
|
"world.CompoundContainerMixin",
|
||||||
"tileentity.BarrelTileEntityMixin",
|
"world.ContainerMixin",
|
||||||
"tileentity.BeaconTileEntityMixin",
|
|
||||||
"tileentity.BeehiveTileEntityMixin",
|
|
||||||
"tileentity.BrewingStandTileEntityMixin",
|
|
||||||
"tileentity.CampfireTileEntityMixin",
|
|
||||||
"tileentity.ChestTileEntityMixin",
|
|
||||||
"tileentity.CommandBlockLogicMixin",
|
|
||||||
"tileentity.CommandBlockTileEntity1Mixin",
|
|
||||||
"tileentity.ConduitTileEntityMixin",
|
|
||||||
"tileentity.DispenserTileEntityMixin",
|
|
||||||
"tileentity.EndGatewayTileEntityMixin",
|
|
||||||
"tileentity.HopperTileEntityMixin",
|
|
||||||
"tileentity.LecternTileEntity1Mixin",
|
|
||||||
"tileentity.LecternTileEntityMixin",
|
|
||||||
"tileentity.LockableTileEntityMixin",
|
|
||||||
"tileentity.ShulkerBoxTileEntityMixin",
|
|
||||||
"tileentity.SignTileEntityMixin",
|
|
||||||
"tileentity.SkullTileEntityMixin",
|
|
||||||
"tileentity.TileEntityMixin",
|
|
||||||
"util.BootstrapMixin",
|
|
||||||
"util.DamageSourceMixin",
|
|
||||||
"util.FoodStatsMixin",
|
|
||||||
"util.IndirectEntityDamageSourceMixin",
|
|
||||||
"util.IWorldPosCallableMixin",
|
|
||||||
"util.text.ColorMixin",
|
|
||||||
"util.text.ITextComponentMixin",
|
|
||||||
"util.text.StyleMixin",
|
|
||||||
"village.VillageSiegeMixin",
|
|
||||||
"world.ExplosionMixin",
|
"world.ExplosionMixin",
|
||||||
"world.IBlockReaderMixin",
|
"world.IBlockReaderMixin",
|
||||||
"world.IServerWorldMixin",
|
"world.IServerWorldMixin",
|
||||||
"world.IWorldMixin",
|
"world.IWorldMixin",
|
||||||
"world.IWorldWriterMixin",
|
"world.IWorldWriterMixin",
|
||||||
"world.TeleporterMixin",
|
"world.SimpleContainerMixin",
|
||||||
"world.TrackedEntityMixin",
|
"world.damagesource.DamageSourceMixin",
|
||||||
"world.WorldMixin",
|
"world.damagesource.IndirectEntityDamageSourceMixin",
|
||||||
"world.biome.BiomeContainerMixin",
|
"world.effect.MobEffectMixin",
|
||||||
"world.border.WorldBorderMixin",
|
|
||||||
"world.chunk.ChunkMixin",
|
|
||||||
"world.chunk.storage.ChunkLoaderMixin",
|
|
||||||
"world.chunk.storage.RegionFileCacheMixin",
|
|
||||||
"world.entity.AgeableMobMixin",
|
"world.entity.AgeableMobMixin",
|
||||||
"world.entity.AreaEffectCloudEntityMixin",
|
"world.entity.AreaEffectCloudEntityMixin",
|
||||||
"world.entity.ItemBaseSteeringMixin",
|
|
||||||
"world.entity.EntityMixin",
|
"world.entity.EntityMixin",
|
||||||
"world.entity.EntityTypeMixin",
|
"world.entity.EntityTypeMixin",
|
||||||
"world.entity.ExperienceOrbMixin",
|
"world.entity.ExperienceOrbMixin",
|
||||||
"world.entity.IAngerableMixin",
|
"world.entity.IAngerableMixin",
|
||||||
|
"world.entity.ItemBaseSteeringMixin",
|
||||||
"world.entity.LightningBoltMixin",
|
"world.entity.LightningBoltMixin",
|
||||||
"world.entity.LivingEntityMixin",
|
"world.entity.LivingEntityMixin",
|
||||||
"world.entity.MobMixin",
|
"world.entity.MobMixin",
|
||||||
|
@ -222,6 +118,7 @@
|
||||||
"world.entity.ai.goal.SkeletonTrapGoalMixin",
|
"world.entity.ai.goal.SkeletonTrapGoalMixin",
|
||||||
"world.entity.ai.goal.TargetGoalMixin",
|
"world.entity.ai.goal.TargetGoalMixin",
|
||||||
"world.entity.ai.goal.TemptGoalMixin",
|
"world.entity.ai.goal.TemptGoalMixin",
|
||||||
|
"world.entity.ai.village.VillageSiegeMixin",
|
||||||
"world.entity.ambient.BatMixin",
|
"world.entity.ambient.BatMixin",
|
||||||
"world.entity.animal.AbstractFishMixin",
|
"world.entity.animal.AbstractFishMixin",
|
||||||
"world.entity.animal.AnimalMixin",
|
"world.entity.animal.AnimalMixin",
|
||||||
|
@ -229,18 +126,40 @@
|
||||||
"world.entity.animal.Bee_HurtByOtherGoalMixin",
|
"world.entity.animal.Bee_HurtByOtherGoalMixin",
|
||||||
"world.entity.animal.BeeMixin",
|
"world.entity.animal.BeeMixin",
|
||||||
"world.entity.animal.BucketableMixin",
|
"world.entity.animal.BucketableMixin",
|
||||||
|
"world.entity.animal.ChickenMixin",
|
||||||
|
"world.entity.animal.CowMixin",
|
||||||
|
"world.entity.animal.DolphinEntity_SwimWithPlayerGoalMixin",
|
||||||
|
"world.entity.animal.DolphinMixin",
|
||||||
|
"world.entity.animal.Fox_BreedGoalMixin",
|
||||||
|
"world.entity.animal.Fox_EatBerriesGoalMixin",
|
||||||
|
"world.entity.animal.FoxMixin",
|
||||||
|
"world.entity.animal.IronGolemMixin",
|
||||||
|
"world.entity.animal.MushroomCowMixin",
|
||||||
|
"world.entity.animal.OcelotMixin",
|
||||||
|
"world.entity.animal.Panda_HurtByTargetGoalMixin",
|
||||||
|
"world.entity.animal.PandaMixin",
|
||||||
|
"world.entity.animal.ParrotMixin",
|
||||||
|
"world.entity.animal.PigMixin",
|
||||||
"world.entity.animal.PufferfishEntityMixin",
|
"world.entity.animal.PufferfishEntityMixin",
|
||||||
|
"world.entity.animal.Rabbit_RaidGardenGoalMixin",
|
||||||
|
"world.entity.animal.RabbitMixin",
|
||||||
|
"world.entity.animal.Sheep1Mixin",
|
||||||
|
"world.entity.animal.SheepMixin",
|
||||||
|
"world.entity.animal.SnowGolemMixin",
|
||||||
|
"world.entity.animal.TameableAnimalMixin",
|
||||||
|
"world.entity.animal.Turtle_LayEggGoalMixin",
|
||||||
|
"world.entity.animal.TurtleMixin",
|
||||||
|
"world.entity.animal.WolfMixin",
|
||||||
"world.entity.animal.horse.AbstractHorseMixin",
|
"world.entity.animal.horse.AbstractHorseMixin",
|
||||||
"world.entity.animal.horse.TraderLlamaEntity_FollowTraderGoalMixin",
|
"world.entity.animal.horse.TraderLlamaEntity_FollowTraderGoalMixin",
|
||||||
"world.entity.boss.WitherEntityMixin",
|
|
||||||
"world.entity.boss.enderdragon.EnderCrystalMixin",
|
"world.entity.boss.enderdragon.EnderCrystalMixin",
|
||||||
"world.entity.boss.enderdragon.EnderDragonMixin",
|
"world.entity.boss.enderdragon.EnderDragonMixin",
|
||||||
"world.entity.boss.enderdragon.phases.EnderDragonPhaseManagerMixin",
|
"world.entity.boss.enderdragon.phases.EnderDragonPhaseManagerMixin",
|
||||||
"world.entity.boss.wither.WitherBossMixin",
|
"world.entity.boss.wither.WitherBossMixin",
|
||||||
|
"world.entity.decoration.ArmorStandMixin",
|
||||||
"world.entity.decoration.ItemFrameMixin",
|
"world.entity.decoration.ItemFrameMixin",
|
||||||
"world.entity.decoration.LeashFenceKnotEntityMixin",
|
"world.entity.decoration.LeashFenceKnotEntityMixin",
|
||||||
"world.entity.decoration.PaintingMixin",
|
"world.entity.decoration.PaintingMixin",
|
||||||
"world.entity.item.ArmorStandEntityMixin",
|
|
||||||
"world.entity.item.FallingBlockEntityMixin",
|
"world.entity.item.FallingBlockEntityMixin",
|
||||||
"world.entity.item.HangingEntityMixin",
|
"world.entity.item.HangingEntityMixin",
|
||||||
"world.entity.item.ItemEntityMixin",
|
"world.entity.item.ItemEntityMixin",
|
||||||
|
@ -275,70 +194,127 @@
|
||||||
"world.entity.npc.AbstractVillagerMixin",
|
"world.entity.npc.AbstractVillagerMixin",
|
||||||
"world.entity.npc.VillagerMixin",
|
"world.entity.npc.VillagerMixin",
|
||||||
"world.entity.npc.WanderingTraderMixin",
|
"world.entity.npc.WanderingTraderMixin",
|
||||||
"world.entity.animal.ChickenMixin",
|
|
||||||
"world.entity.animal.CowMixin",
|
|
||||||
"world.entity.animal.DolphinEntity_SwimWithPlayerGoalMixin",
|
|
||||||
"world.entity.animal.DolphinMixin",
|
|
||||||
"world.entity.animal.Fox_EatBerriesGoalMixin",
|
|
||||||
"world.entity.animal.Fox_BreedGoalMixin",
|
|
||||||
"world.entity.passive.FoxEntity_RevengeGoalMixin",
|
|
||||||
"world.entity.animal.FoxMixin",
|
|
||||||
"world.entity.animal.IronGolemMixin",
|
|
||||||
"world.entity.animal.MushroomCowMixin",
|
|
||||||
"world.entity.animal.OcelotMixin",
|
|
||||||
"world.entity.animal.Panda_HurtByTargetGoalMixin",
|
|
||||||
"world.entity.animal.PandaMixin",
|
|
||||||
"world.entity.animal.ParrotMixin",
|
|
||||||
"world.entity.animal.PigMixin",
|
|
||||||
"world.entity.animal.Rabbit_RaidGardenGoalMixin",
|
|
||||||
"world.entity.animal.RabbitMixin",
|
|
||||||
"world.entity.animal.Sheep1Mixin",
|
|
||||||
"world.entity.animal.SheepMixin",
|
|
||||||
"world.entity.animal.SnowGolemMixin",
|
|
||||||
"world.entity.animal.TameableAnimalMixin",
|
|
||||||
"world.entity.animal.Turtle_LayEggGoalMixin",
|
|
||||||
"world.entity.animal.TurtleMixin",
|
|
||||||
"world.entity.animal.WolfMixin",
|
|
||||||
"world.entity.player.PlayerMixin",
|
|
||||||
"world.entity.player.InventoryMixin",
|
"world.entity.player.InventoryMixin",
|
||||||
|
"world.entity.player.PlayerMixin",
|
||||||
"world.entity.player.ServerPlayerMixin",
|
"world.entity.player.ServerPlayerMixin",
|
||||||
"world.entity.projectile.AbstractArrowMixin",
|
"world.entity.projectile.AbstractArrowMixin",
|
||||||
"world.entity.projectile.FireballMixin",
|
|
||||||
"world.entity.projectile.ArrowEntityMixin",
|
|
||||||
"world.entity.projectile.AbstractHurtingProjectileMixin",
|
"world.entity.projectile.AbstractHurtingProjectileMixin",
|
||||||
"world.entity.projectile.ThrownEggMixin",
|
"world.entity.projectile.ArrowEntityMixin",
|
||||||
"world.entity.projectile.EvokerFangsMixin",
|
"world.entity.projectile.EvokerFangsMixin",
|
||||||
"world.entity.projectile.LargeFireballMixin",
|
"world.entity.projectile.FireballMixin",
|
||||||
"world.entity.projectile.FireworkRocketEntityMixin",
|
"world.entity.projectile.FireworkRocketEntityMixin",
|
||||||
"world.entity.projectile.FishingHookMixin",
|
"world.entity.projectile.FishingHookMixin",
|
||||||
"world.entity.projectile.ThrownPotionMixin",
|
"world.entity.projectile.LargeFireballMixin",
|
||||||
"world.entity.projectile.ProjectileMixin",
|
"world.entity.projectile.ProjectileMixin",
|
||||||
"world.entity.projectile.ShulkerBulletMixin",
|
"world.entity.projectile.ShulkerBulletMixin",
|
||||||
"world.entity.projectile.SmallFireballMixin",
|
"world.entity.projectile.SmallFireballMixin",
|
||||||
"world.entity.projectile.SpectralArrowMixin",
|
"world.entity.projectile.SpectralArrowMixin",
|
||||||
"world.entity.projectile.ThrowableItemProjectileMixin",
|
"world.entity.projectile.ThrowableItemProjectileMixin",
|
||||||
"world.entity.projectile.ThrowableProjectileMixin",
|
"world.entity.projectile.ThrowableProjectileMixin",
|
||||||
|
"world.entity.projectile.ThrownEggMixin",
|
||||||
"world.entity.projectile.ThrownEnderpearlMixin",
|
"world.entity.projectile.ThrownEnderpearlMixin",
|
||||||
"world.entity.projectile.ThrownExperienceBottleMixin",
|
"world.entity.projectile.ThrownExperienceBottleMixin",
|
||||||
|
"world.entity.projectile.ThrownPotionMixin",
|
||||||
"world.entity.projectile.ThrownTridentMixin",
|
"world.entity.projectile.ThrownTridentMixin",
|
||||||
"world.entity.projectile.WitherSkullMixin",
|
"world.entity.projectile.WitherSkullMixin",
|
||||||
|
"world.entity.raid.RaidManagerMixin",
|
||||||
|
"world.entity.raid.RaidMixin",
|
||||||
"world.entity.raider.Raider_HoldGroundAttackGoalMixin",
|
"world.entity.raider.Raider_HoldGroundAttackGoalMixin",
|
||||||
"world.entity.raider.RaiderMixin",
|
"world.entity.raider.RaiderMixin",
|
||||||
"world.entity.vehicle.AbstractMinecartContainerMixin",
|
"world.entity.vehicle.AbstractMinecartContainerMixin",
|
||||||
"world.entity.vehicle.AbstractMinecartMixin",
|
"world.entity.vehicle.AbstractMinecartMixin",
|
||||||
"world.entity.vehicle.BoatMixin",
|
"world.entity.vehicle.BoatMixin",
|
||||||
"world.entity.vehicle.MinecartCommandBlock_MinecartCommandBaseMixin",
|
"world.entity.vehicle.MinecartCommandBlock_MinecartCommandBaseMixin",
|
||||||
|
"world.food.FoodDataMixin",
|
||||||
"world.gen.WorldGenRegionMixin",
|
"world.gen.WorldGenRegionMixin",
|
||||||
"world.gen.feature.structure.StructureManagerMixin",
|
"world.gen.feature.structure.StructureManagerMixin",
|
||||||
"world.gen.feature.structure.SwampHutPieceMixin",
|
"world.gen.feature.structure.SwampHutPieceMixin",
|
||||||
"world.gen.feature.template.TemplateManagerMixin",
|
"world.gen.feature.template.TemplateManagerMixin",
|
||||||
|
"world.inventory.AbstractContainerMenuMixin",
|
||||||
|
"world.inventory.AbstractFurnaceContainerMixin",
|
||||||
|
"world.inventory.BeaconContainerMixin",
|
||||||
|
"world.inventory.BrewingStandContainerMixin",
|
||||||
|
"world.inventory.CartographyContainer1Mixin",
|
||||||
|
"world.inventory.CartographyContainer2Mixin",
|
||||||
|
"world.inventory.CartographyContainerMixin",
|
||||||
|
"world.inventory.ChestContainerMixin",
|
||||||
|
"world.inventory.ContainerLevelAccessMixin",
|
||||||
|
"world.inventory.ContainerTypeMixin",
|
||||||
|
"world.inventory.CraftingInventoryMixin",
|
||||||
|
"world.inventory.CraftingMenuMixin",
|
||||||
|
"world.inventory.CraftResultInventoryMixin",
|
||||||
|
"world.inventory.DispenserContainerMixin",
|
||||||
|
"world.inventory.EnchantmentContainer1Mixin",
|
||||||
|
"world.inventory.EnchantmentContainerMixin",
|
||||||
|
"world.inventory.EnderChestInventoryMixin",
|
||||||
|
"world.inventory.FurnaceResultSlotMixin",
|
||||||
|
"world.inventory.GrindstoneContainer1Mixin",
|
||||||
|
"world.inventory.GrindstoneContainerMixin",
|
||||||
|
"world.inventory.HopperContainerMixin",
|
||||||
|
"world.inventory.HorseInventoryContainerMixin",
|
||||||
|
"world.inventory.ItemCombinerMixin",
|
||||||
|
"world.inventory.LecternContainerMixin",
|
||||||
|
"world.inventory.LoomContainer1Mixin",
|
||||||
|
"world.inventory.LoomContainer2Mixin",
|
||||||
|
"world.inventory.LoomContainerMixin",
|
||||||
|
"world.inventory.MerchantContainerMixin",
|
||||||
|
"world.inventory.MerchantInventoryMixin",
|
||||||
|
"world.inventory.PlayerContainerMixin",
|
||||||
|
"world.inventory.RepairContainerMixin",
|
||||||
|
"world.inventory.ShulkerBoxContainerMixin",
|
||||||
|
"world.inventory.SlotMixin",
|
||||||
|
"world.inventory.SmithingTableContainerMixin",
|
||||||
|
"world.inventory.StonecutterContainer1Mixin",
|
||||||
|
"world.inventory.StonecutterContainerMixin",
|
||||||
|
"world.item.ArmorStandItemMixin",
|
||||||
|
"world.item.BlockItemMixin",
|
||||||
|
"world.item.BoatItemMixin",
|
||||||
|
"world.item.BowItemMixin",
|
||||||
|
"world.item.BucketItemMixin",
|
||||||
|
"world.item.ChorusFruitItemMixin",
|
||||||
|
"world.item.CrossbowItemMixin",
|
||||||
|
"world.item.DyeItemMixin",
|
||||||
|
"world.item.EggItemMixin",
|
||||||
|
"world.item.EnderCrystalItemMixin",
|
||||||
|
"world.item.EnderEyeItemMixin",
|
||||||
|
"world.item.EnderPearlItemMixin",
|
||||||
|
"world.item.FireChargeItemMixin",
|
||||||
|
"world.item.FishingRodItemMixin",
|
||||||
|
"world.item.FlintAndSteelItemMixin",
|
||||||
|
"world.item.HangingEntityItemMixin",
|
||||||
|
"world.item.ItemStackMixin",
|
||||||
|
"world.item.LeadItemMixin",
|
||||||
|
"world.item.MapItemMixin",
|
||||||
"world.item.MerchantMixin",
|
"world.item.MerchantMixin",
|
||||||
|
"world.item.MerchantOfferMixin",
|
||||||
|
"world.item.MilkBucketItemMixin",
|
||||||
|
"world.item.MinecartItemMixin",
|
||||||
|
"world.item.PotionItemMixin",
|
||||||
|
"world.item.ShearsItemMixin",
|
||||||
|
"world.item.SnowballItemMixin",
|
||||||
|
"world.item.SpawnEggItemMixin",
|
||||||
|
"world.item.TridentItemMixin",
|
||||||
|
"world.item.crafting.BlastingRecipeMixin",
|
||||||
|
"world.item.crafting.CampfireCookingRecipeMixin",
|
||||||
|
"world.item.crafting.CustomRecipeMixin",
|
||||||
|
"world.item.crafting.FurnaceRecipeMixin",
|
||||||
|
"world.item.crafting.IngredientMixin",
|
||||||
|
"world.item.crafting.RecipeManagerMixin",
|
||||||
|
"world.item.crafting.RecipeMixin",
|
||||||
|
"world.item.crafting.ServerRecipeBookMixin",
|
||||||
|
"world.item.crafting.ShapedRecipeMixin",
|
||||||
|
"world.item.crafting.ShapelessRecipeMixin",
|
||||||
|
"world.item.crafting.SmithingRecipeMixin",
|
||||||
|
"world.item.crafting.SmokingRecipeMixin",
|
||||||
|
"world.item.crafting.StonecuttingRecipeMixin",
|
||||||
"world.item.enchantment.DamageEnchantmentMixin",
|
"world.item.enchantment.DamageEnchantmentMixin",
|
||||||
"world.item.enchantment.FrostWalkerEnchantmentMixin",
|
"world.item.enchantment.FrostWalkerEnchantmentMixin",
|
||||||
|
"world.level.LevelMixin",
|
||||||
"world.level.block.BambooBlockMixin",
|
"world.level.block.BambooBlockMixin",
|
||||||
"world.level.block.BambooSaplingBlockMixin",
|
"world.level.block.BambooSaplingBlockMixin",
|
||||||
"world.level.block.BaseFireBlockMixin",
|
"world.level.block.BaseFireBlockMixin",
|
||||||
"world.level.block.BasePressurePlateBlockMixin",
|
"world.level.block.BasePressurePlateBlockMixin",
|
||||||
|
"world.level.block.BedBlockMixin",
|
||||||
"world.level.block.BeehiveBlockMixin",
|
"world.level.block.BeehiveBlockMixin",
|
||||||
"world.level.block.BlockMixin",
|
"world.level.block.BlockMixin",
|
||||||
"world.level.block.BushBlockMixin",
|
"world.level.block.BushBlockMixin",
|
||||||
|
@ -421,18 +397,44 @@
|
||||||
"world.level.block.WeightedPressurePlateBlockMixin",
|
"world.level.block.WeightedPressurePlateBlockMixin",
|
||||||
"world.level.block.WitherRoseBlockMixin",
|
"world.level.block.WitherRoseBlockMixin",
|
||||||
"world.level.block.WitherSkullBlockMixin",
|
"world.level.block.WitherSkullBlockMixin",
|
||||||
|
"world.level.block.entity.AbstractFurnaceBlockEntityMixin",
|
||||||
|
"world.level.block.entity.BarrelBlockEntityMixin",
|
||||||
|
"world.level.block.entity.BeaconTileEntityMixin",
|
||||||
|
"world.level.block.entity.BeehiveBlockEntityMixin",
|
||||||
|
"world.level.block.entity.BlockEntityMixin",
|
||||||
|
"world.level.block.entity.BrewingStandBlockEntityMixin",
|
||||||
|
"world.level.block.entity.CampfireTileEntityMixin",
|
||||||
|
"world.level.block.entity.ChestBlockEntityMixin",
|
||||||
|
"world.level.block.entity.CommandBlockLogicMixin",
|
||||||
|
"world.level.block.entity.CommandBlockTileEntity1Mixin",
|
||||||
|
"world.level.block.entity.ConduitBlockEntityMixin",
|
||||||
|
"world.level.block.entity.DispenserBlockEntityMixin",
|
||||||
|
"world.level.block.entity.EndGatewayBlockEntityMixin",
|
||||||
|
"world.level.block.entity.HopperBlockEntityMixin",
|
||||||
|
"world.level.block.entity.LecternBlockEntityMixin",
|
||||||
|
"world.level.block.entity.LecternTileEntity1Mixin",
|
||||||
|
"world.level.block.entity.LockableBlockEntityMixin",
|
||||||
|
"world.level.block.entity.ShulkerBoxBlockEntityMixin",
|
||||||
|
"world.level.block.entity.SignBlockEntityMixin",
|
||||||
"world.level.block.state.BlockBehaviour_BlockStateBaseMixin",
|
"world.level.block.state.BlockBehaviour_BlockStateBaseMixin",
|
||||||
"world.level.block.state.BlockBehaviourMixin",
|
"world.level.block.state.BlockBehaviourMixin",
|
||||||
"world.raid.RaidManagerMixin",
|
"world.level.block.state.properties.IntegerPropertyMixin",
|
||||||
"world.raid.RaidMixin",
|
"world.level.border.WorldBorderMixin",
|
||||||
"world.server.ChunkHolderMixin",
|
"world.level.chunk.ChunkBiomeContainerMixin",
|
||||||
"world.server.ChunkManager_EntityTrackerMixin",
|
"world.level.chunk.LevelChunk_BoundTickingBlockEntityMixin",
|
||||||
"world.server.ChunkManagerMixin",
|
"world.level.chunk.LevelChunkMixin",
|
||||||
"world.server.ServerChunkProvider_ChunkExecutorMixin",
|
"world.level.chunk.storage.ChunkLoaderMixin",
|
||||||
"world.server.ServerChunkProviderMixin",
|
"world.level.chunk.storage.RegionFileCacheMixin",
|
||||||
"world.server.ServerWorldMixin",
|
"world.level.portal.PortalForcerMixin",
|
||||||
"world.server.TicketManagerMixin",
|
"world.level.saveddata.maps.MapData_MapInfoMixin",
|
||||||
"world.server.TicketTypeMixin",
|
"world.level.saveddata.maps.MapDataMixin",
|
||||||
|
"world.level.storage.loot.LootTableManagerMixin",
|
||||||
|
"world.level.storage.loot.LootTableMixin",
|
||||||
|
"world.level.storage.loot.entries.LootEntry_SerializerMixin",
|
||||||
|
"world.level.storage.loot.functions.LootingEnchantBonusMixin",
|
||||||
|
"world.level.storage.loot.parameters.LootParametersMixin",
|
||||||
|
"world.level.storage.loot.predicates.RandomChanceWithLootingMixin",
|
||||||
|
"world.level.storage.loot.predicates.SurvivesExplosionMixin",
|
||||||
"world.spawner.AbstractSpawnerMixin",
|
"world.spawner.AbstractSpawnerMixin",
|
||||||
"world.spawner.PatrolSpawnerMixin",
|
"world.spawner.PatrolSpawnerMixin",
|
||||||
"world.spawner.PhantomSpawnerMixin",
|
"world.spawner.PhantomSpawnerMixin",
|
||||||
|
@ -440,8 +442,6 @@
|
||||||
"world.spawner.WorldEntitySpawner_EntityDensityManagerMixin",
|
"world.spawner.WorldEntitySpawner_EntityDensityManagerMixin",
|
||||||
"world.spawner.WorldEntitySpawnerMixin",
|
"world.spawner.WorldEntitySpawnerMixin",
|
||||||
"world.storage.DerivedWorldInfoMixin",
|
"world.storage.DerivedWorldInfoMixin",
|
||||||
"world.storage.MapData_MapInfoMixin",
|
|
||||||
"world.storage.MapDataMixin",
|
|
||||||
"world.storage.PlayerDataMixin",
|
"world.storage.PlayerDataMixin",
|
||||||
"world.storage.SaveFormat_LevelSaveMixin",
|
"world.storage.SaveFormat_LevelSaveMixin",
|
||||||
"world.storage.SaveFormatMixin",
|
"world.storage.SaveFormatMixin",
|
||||||
|
|
|
@ -23,7 +23,7 @@ apply plugin: 'maven-publish'
|
||||||
arclight {
|
arclight {
|
||||||
mcVersion = minecraftVersion
|
mcVersion = minecraftVersion
|
||||||
forgeVersion = project.ext.forgeVersion
|
forgeVersion = project.ext.forgeVersion
|
||||||
bukkitVersion = 'v1_16_R3'
|
bukkitVersion = 'v1_17_R1'
|
||||||
wipeVersion = true
|
wipeVersion = true
|
||||||
reobfVersion = true
|
reobfVersion = true
|
||||||
accessTransformer = project(':arclight-common').file('bukkit.at')
|
accessTransformer = project(':arclight-common').file('bukkit.at')
|
||||||
|
@ -86,6 +86,7 @@ def embedLibs = [/*'org.spongepowered:mixin:0.8.1',*/ 'org.ow2.asm:asm-util:9.0'
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft "net.minecraftforge:forge:$minecraftVersion-$forgeVersion"
|
minecraft "net.minecraftforge:forge:$minecraftVersion-$forgeVersion"
|
||||||
implementation group: 'org.jetbrains', name: 'annotations', version: '19.0.0'
|
implementation group: 'org.jetbrains', name: 'annotations', version: '19.0.0'
|
||||||
|
implementation 'org.spongepowered:mixin:0.8.3'
|
||||||
implementation(project(':arclight-common')) {
|
implementation(project(':arclight-common')) {
|
||||||
exclude module: 'forge'
|
exclude module: 'forge'
|
||||||
}
|
}
|
||||||
|
@ -102,7 +103,7 @@ dependencies {
|
||||||
embed 'com.github.ArclightTeam:mixin-tools:1.0.0@jar'
|
embed 'com.github.ArclightTeam:mixin-tools:1.0.0@jar'
|
||||||
embed "io.izzel:tools:$toolsVersion"
|
embed "io.izzel:tools:$toolsVersion"
|
||||||
embed "io.izzel.arclight:arclight-api:$apiVersion"
|
embed "io.izzel.arclight:arclight-api:$apiVersion"
|
||||||
annotationProcessor 'org.spongepowered:mixin:0.8.2:processor'
|
annotationProcessor 'org.spongepowered:mixin:0.8.3:processor'
|
||||||
annotationProcessor 'com.github.ArclightTeam:mixin-tools:1.0.0'
|
annotationProcessor 'com.github.ArclightTeam:mixin-tools:1.0.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,13 @@ package io.izzel.arclight.impl.common.optimization;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
|
import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
|
||||||
import it.unimi.dsi.fastutil.doubles.DoubleList;
|
import it.unimi.dsi.fastutil.doubles.DoubleList;
|
||||||
import net.minecraft.util.math.shapes.IDoubleListMerger;
|
import net.minecraft.world.phys.shapes.IndexMerger;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author jellysquid3 (LGPLv3)
|
* @author jellysquid3 (LGPLv3)
|
||||||
*/
|
*/
|
||||||
public class OptimizedIndirectMerger implements IDoubleListMerger {
|
public class OptimizedIndirectMerger implements IndexMerger {
|
||||||
|
|
||||||
private final double[] merged;
|
private final double[] merged;
|
||||||
private final int[] indicesFirst;
|
private final int[] indicesFirst;
|
||||||
|
@ -108,12 +108,12 @@ public class OptimizedIndirectMerger implements IDoubleListMerger {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull DoubleList func_212435_a() {
|
public @NotNull DoubleList getList() {
|
||||||
return this.pairs;
|
return this.pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean forMergedIndexes(@NotNull IConsumer consumer) {
|
public boolean forMergedIndexes(@NotNull IndexConsumer consumer) {
|
||||||
int l = this.pairs.size() - 1;
|
int l = this.pairs.size() - 1;
|
||||||
|
|
||||||
for (int i = 0; i < l; i++) {
|
for (int i = 0; i < l; i++) {
|
||||||
|
@ -124,4 +124,9 @@ public class OptimizedIndirectMerger implements IDoubleListMerger {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return this.pairs.size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,18 @@ package io.izzel.arclight.impl.mixin.optimization.dfu;
|
||||||
|
|
||||||
import com.mojang.datafixers.DataFixer;
|
import com.mojang.datafixers.DataFixer;
|
||||||
import com.mojang.datafixers.DataFixerBuilder;
|
import com.mojang.datafixers.DataFixerBuilder;
|
||||||
import net.minecraft.util.SharedConstants;
|
import net.minecraft.SharedConstants;
|
||||||
import net.minecraft.util.datafix.DataFixesManager;
|
import net.minecraft.util.datafix.DataFixers;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
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.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
@Mixin(DataFixesManager.class)
|
@Mixin(DataFixers.class)
|
||||||
public class DataFixesManagerMixin {
|
public class DataFixesManagerMixin {
|
||||||
|
|
||||||
@Inject(method = "createFixer", cancellable = true, at = @At("HEAD"))
|
@Inject(method = "createFixerUpper", cancellable = true, at = @At("HEAD"))
|
||||||
private static void arclight$disableDfu(CallbackInfoReturnable<DataFixer> cir) {
|
private static void arclight$disableDfu(CallbackInfoReturnable<DataFixer> cir) {
|
||||||
cir.setReturnValue(new DataFixerBuilder(SharedConstants.getVersion().getWorldVersion()).build(r -> {}));
|
cir.setReturnValue(new DataFixerBuilder(SharedConstants.getCurrentVersion().getWorldVersion()).build(r -> {}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
package io.izzel.arclight.impl.mixin.optimization.dfu;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.entity.EntityClassification;
|
|
||||||
import net.minecraft.entity.EntitySize;
|
|
||||||
import net.minecraft.entity.EntityType;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraftforge.fml.network.FMLPlayMessages;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
import java.util.function.ToIntFunction;
|
|
||||||
|
|
||||||
@Mixin(EntityType.Builder.class)
|
|
||||||
public class EntityType_BuilderMixin<T extends Entity> {
|
|
||||||
|
|
||||||
@Shadow private boolean serializable;
|
|
||||||
@Shadow @Final private EntityType.IFactory<T> factory;
|
|
||||||
@Shadow @Final private EntityClassification classification;
|
|
||||||
@Shadow private boolean summonable;
|
|
||||||
@Shadow private boolean immuneToFire;
|
|
||||||
@Shadow private boolean field_225436_f;
|
|
||||||
@Shadow private EntitySize size;
|
|
||||||
@Shadow private Predicate<EntityType<?>> velocityUpdateSupplier;
|
|
||||||
@Shadow private ToIntFunction<EntityType<?>> trackingRangeSupplier;
|
|
||||||
@Shadow private ToIntFunction<EntityType<?>> updateIntervalSupplier;
|
|
||||||
@Shadow private BiFunction<FMLPlayMessages.SpawnEntity, World, T> customClientFactory;
|
|
||||||
@Shadow private int field_233605_i_;
|
|
||||||
@Shadow private int trackingRange;
|
|
||||||
@Shadow private ImmutableSet<Block> field_233603_c_;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Izzel_Aliz
|
|
||||||
* @reason
|
|
||||||
*/
|
|
||||||
@Overwrite
|
|
||||||
public EntityType<T> build(String id) {
|
|
||||||
return new EntityType<>(this.factory, this.classification, this.serializable, this.summonable, this.immuneToFire, this.field_225436_f, this.field_233603_c_, this.size, this.trackingRange, this.field_233605_i_, velocityUpdateSupplier, trackingRangeSupplier, updateIntervalSupplier, customClientFactory);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,7 +2,7 @@ package io.izzel.arclight.impl.mixin.optimization.dfu;
|
||||||
|
|
||||||
import io.izzel.arclight.i18n.ArclightLocale;
|
import io.izzel.arclight.i18n.ArclightLocale;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.world.storage.SaveFormat;
|
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
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;
|
||||||
|
@ -11,9 +11,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
@Mixin(MinecraftServer.class)
|
@Mixin(MinecraftServer.class)
|
||||||
public abstract class MinecraftServerMixin {
|
public abstract class MinecraftServerMixin {
|
||||||
|
|
||||||
@Inject(method = "func_240777_a_", cancellable = true, at = @At("HEAD"))
|
@Inject(method = "convertFromRegionFormatIfNeeded", cancellable = true, at = @At("HEAD"))
|
||||||
private static void arclight$skipConvert(SaveFormat.LevelSave levelSave, CallbackInfo ci) {
|
private static void arclight$skipConvert(LevelStorageSource.LevelStorageAccess levelSave, CallbackInfo ci) {
|
||||||
if (levelSave.isSaveFormatOutdated()) {
|
if (levelSave.requiresConversion()) {
|
||||||
throw new RuntimeException(ArclightLocale.getInstance().get("dfu-disable.map-convert"));
|
throw new RuntimeException(ArclightLocale.getInstance().get("dfu-disable.map-convert"));
|
||||||
}
|
}
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
package io.izzel.arclight.impl.mixin.optimization.dfu;
|
|
||||||
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
|
||||||
import net.minecraft.tileentity.TileEntityType;
|
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
|
||||||
|
|
||||||
@Mixin(TileEntityType.class)
|
|
||||||
public class TileEntityTypeMixin {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author IzzelAliz
|
|
||||||
* @reason
|
|
||||||
*/
|
|
||||||
@Overwrite
|
|
||||||
private static <T extends TileEntity> TileEntityType<T> register(String key, TileEntityType.Builder<T> builder) {
|
|
||||||
return Registry.register(Registry.BLOCK_ENTITY_TYPE, key, builder.build(null));
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user