merge upstream 26.2
This commit is contained in:
264 files changed
+4991
-4042
No files matched your search
@@ -70,12 +70,6 @@ public interface CarpetExtension
|
||||
registerCommands(dispatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Implement {@link #extensionSettingsManager()} instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
default carpet.settings.SettingsManager customSettingsManager() {return null;}
|
||||
|
||||
/**
|
||||
* Provide your own custom settings manager managed in the same way as base /carpet
|
||||
* command, but separated to its own command as defined in SettingsManager.
|
||||
@@ -84,13 +78,7 @@ public interface CarpetExtension
|
||||
*
|
||||
*/
|
||||
default SettingsManager extensionSettingsManager() {
|
||||
// Warn extensions overriding the other (deprecated) method, go ahead and override this if you want to provide a custom SettingsManager
|
||||
SettingsManager deprecatedManager = customSettingsManager();
|
||||
if (deprecatedManager != null) {
|
||||
// Extension is providing a manager via the old method (and also hasn't overriden this)
|
||||
CarpetServer.warnOutdatedManager(this);
|
||||
}
|
||||
return customSettingsManager();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,6 +40,8 @@ import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.commands.PerfCommand;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class CarpetServer // static for now - easier to handle all around the code, its one anyways
|
||||
{
|
||||
public static MinecraftServer minecraft_server;
|
||||
@@ -160,7 +162,7 @@ public class CarpetServer // static for now - easier to handle all around the co
|
||||
LoggerRegistry.playerDisconnected(player);
|
||||
extensions.forEach(e -> e.onPlayerLoggedOut(player));
|
||||
// first case client, second case server
|
||||
CarpetScriptServer runningScriptServer = (player.getServer() == null) ? scriptServer : Vanilla.MinecraftServer_getScriptServer(player.getServer());
|
||||
CarpetScriptServer runningScriptServer = (player.level().getServer() == null) ? scriptServer : Vanilla.MinecraftServer_getScriptServer(player.level().getServer());
|
||||
if (runningScriptServer != null && !runningScriptServer.stopAll) {
|
||||
runningScriptServer.onPlayerLoggedOut(player, reason);
|
||||
}
|
||||
@@ -172,7 +174,7 @@ public class CarpetServer // static for now - easier to handle all around the co
|
||||
scriptServer = null;
|
||||
}
|
||||
|
||||
public static void onServerClosed(MinecraftServer server)
|
||||
public static void onServerClosed(@Nullable MinecraftServer server)
|
||||
{
|
||||
// this for whatever reason gets called multiple times even when joining on SP
|
||||
// so we allow to pass multiple times gating it only on existing server ref
|
||||
@@ -180,7 +182,7 @@ public class CarpetServer // static for now - easier to handle all around the co
|
||||
{
|
||||
if (scriptServer != null) scriptServer.onClose();
|
||||
// this is a mess, will cleanip onlly when global reference is gone
|
||||
if (!Vanilla.MinecraftServer_getScriptServer(server).stopAll) {
|
||||
if (server != null && !Vanilla.MinecraftServer_getScriptServer(server).stopAll) {
|
||||
Vanilla.MinecraftServer_getScriptServer(server).onClose();
|
||||
}
|
||||
|
||||
@@ -224,14 +226,5 @@ public class CarpetServer // static for now - easier to handle all around the co
|
||||
scriptServer.reload(server);
|
||||
extensions.forEach(e -> e.onReload(server));
|
||||
}
|
||||
|
||||
private static final Set<CarpetExtension> warnedOutdatedManagerProviders = new HashSet<>();
|
||||
static void warnOutdatedManager(CarpetExtension ext)
|
||||
{
|
||||
if (warnedOutdatedManagerProviders.add(ext))
|
||||
CarpetSettings.LOG.warn("""
|
||||
%s is providing a SettingsManager from an outdated method in CarpetExtension!
|
||||
This behaviour will not work in later Carpet versions and the manager won't be registered!""".formatted(ext.getClass().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,12 +12,16 @@ import carpet.utils.Messenger;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.SemanticVersion;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.Commands;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.ServerInterface;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.permissions.LevelBasedPermissionSet;
|
||||
import net.minecraft.server.permissions.PermissionCheck;
|
||||
import net.minecraft.server.permissions.PermissionSet;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
@@ -56,7 +60,7 @@ public class CarpetSettings
|
||||
public static final Logger LOG = LoggerFactory.getLogger("carpet");
|
||||
public static final ThreadLocal<Boolean> skipGenerationChecks = ThreadLocal.withInitial(() -> false);
|
||||
public static final ThreadLocal<Boolean> impendingFillSkipUpdates = ThreadLocal.withInitial(() -> false);
|
||||
public static int runPermissionLevel = 2;
|
||||
public static PermissionSet runPermissionLevel = LevelBasedPermissionSet.GAMEMASTER;
|
||||
public static Block structureBlockIgnoredBlock = Blocks.STRUCTURE_VOID;
|
||||
private static class LanguageValidator extends Validator<String> {
|
||||
@Override public String validate(CommandSourceStack source, CarpetRule<String> currentRule, String newValue, String string) {
|
||||
@@ -73,7 +77,7 @@ public class CarpetSettings
|
||||
@Rule(
|
||||
desc = "Sets the language for Carpet",
|
||||
category = FEATURE,
|
||||
options = {"en_us", "fr_fr", "pt_br", "zh_cn", "zh_tw"},
|
||||
options = {"en_us", "fr_fr", "es_ar","pt_br", "zh_cn", "zh_tw"},
|
||||
strict = true, // the current system doesn't handle fallbacks and other, not defined languages would make unreadable mess. Change later
|
||||
validate = LanguageValidator.class
|
||||
)
|
||||
@@ -129,7 +133,7 @@ public class CarpetSettings
|
||||
|
||||
private static class CarpetPermissionLevel extends Validator<String> {
|
||||
@Override public String validate(CommandSourceStack source, CarpetRule<String> currentRule, String newValue, String string) {
|
||||
if (source == null || source.hasPermission(4))
|
||||
if (source == null || Commands.LEVEL_OWNERS.check(source.permissions()))
|
||||
return newValue;
|
||||
return null;
|
||||
}
|
||||
@@ -152,9 +156,6 @@ public class CarpetSettings
|
||||
@Rule(desc = "Gbhs sgnf sadsgras fhskdpri!!!", category = EXPERIMENTAL)
|
||||
public static boolean superSecretSetting = false;
|
||||
|
||||
@Rule(desc = "Dropping entire stacks works also from on the crafting UI result slot", category = {RuleCategory.BUGFIX, SURVIVAL})
|
||||
public static boolean ctrlQCraftingFix = false;
|
||||
|
||||
@Rule(desc = "Parrots don't get of your shoulders until you receive proper damage", category = {SURVIVAL, FEATURE})
|
||||
public static boolean persistentParrots = false;
|
||||
|
||||
@@ -423,10 +424,32 @@ public class CarpetSettings
|
||||
@Rule(
|
||||
desc = "Required permission level for /perf command",
|
||||
options = {"2", "4"},
|
||||
category = CREATIVE
|
||||
category = CREATIVE,
|
||||
validate = PermissionValidator.class
|
||||
)
|
||||
public static int perfPermissionLevel = 4;
|
||||
|
||||
public static class PermissionValidator extends Validator<Integer> {
|
||||
@Override
|
||||
public Integer validate(CommandSourceStack source, CarpetRule<Integer> currentRule, Integer newValue, String string) {
|
||||
if (newValue == 2) {
|
||||
perfPermissionCheck = Commands.LEVEL_GAMEMASTERS;
|
||||
|
||||
} else if (newValue == 4) {
|
||||
perfPermissionCheck = Commands.LEVEL_OWNERS;
|
||||
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "You must have the permission level you are trying to set";
|
||||
}
|
||||
}
|
||||
public static PermissionCheck perfPermissionCheck = Commands.LEVEL_OWNERS;
|
||||
|
||||
|
||||
@Rule(desc = "Enables /log command to monitor events via chat and overlays", category = COMMAND)
|
||||
public static String commandLog = "true";
|
||||
|
||||
@@ -476,17 +499,21 @@ public class CarpetSettings
|
||||
|
||||
private static class ModulePermissionLevel extends Validator<String> {
|
||||
@Override public String validate(CommandSourceStack source, CarpetRule<String> currentRule, String newValue, String string) {
|
||||
int permissionLevel = switch (newValue) {
|
||||
case "false" -> 0;
|
||||
case "true", "ops" -> 2;
|
||||
case "0", "1", "2", "3", "4" -> Integer.parseInt(newValue);
|
||||
PermissionCheck permissionLevel = switch (newValue) {
|
||||
case "0", "false" -> Commands.LEVEL_ALL;
|
||||
case "1" -> Commands.LEVEL_MODERATORS;
|
||||
case "2", "true", "ops" -> Commands.LEVEL_GAMEMASTERS;
|
||||
case "3" -> Commands.LEVEL_ADMINS;
|
||||
case "4" -> Commands.LEVEL_OWNERS;
|
||||
default -> throw new IllegalArgumentException(); // already checked by previous validator
|
||||
};
|
||||
if (source != null && !source.hasPermission(permissionLevel))
|
||||
if (source != null && !permissionLevel.check(source.permissions()))
|
||||
return null;
|
||||
CarpetSettings.runPermissionLevel = permissionLevel;
|
||||
if (source != null)
|
||||
CarpetSettings.runPermissionLevel = LevelBasedPermissionSet.GAMEMASTER;
|
||||
if (source != null) {
|
||||
CommandHelper.notifyPlayersCommandsChanged(source.getServer());
|
||||
CarpetSettings.runPermissionLevel =source.permissions();
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
@Override
|
||||
@@ -708,7 +735,7 @@ public class CarpetSettings
|
||||
|
||||
if (server.isDedicatedServer())
|
||||
{
|
||||
int vd = (newValue >= 2)?newValue:((ServerInterface) server).getProperties().viewDistance;
|
||||
int vd = (newValue >= 2)?newValue:((ServerInterface) server).getProperties().viewDistance.get();
|
||||
if (vd != server.getPlayerList().getViewDistance())
|
||||
server.getPlayerList().setViewDistance(vd);
|
||||
return newValue;
|
||||
@@ -749,7 +776,7 @@ public class CarpetSettings
|
||||
|
||||
if (server.isDedicatedServer())
|
||||
{
|
||||
int vd = (newValue >= 2)?newValue:((DedicatedServer) server).getProperties().simulationDistance;
|
||||
int vd = (newValue >= 2)?newValue:((DedicatedServer) server).getProperties().simulationDistance.get();
|
||||
if (vd != server.getPlayerList().getSimulationDistance())
|
||||
server.getPlayerList().setSimulationDistance(vd);
|
||||
return newValue;
|
||||
@@ -908,7 +935,7 @@ public class CarpetSettings
|
||||
@Override
|
||||
public String validate(CommandSourceStack source, CarpetRule<String> currentRule, String newValue, String string) {
|
||||
if (source == null) return newValue; // closing or sync
|
||||
Optional<Block> ignoredBlock = source.registryAccess().registryOrThrow(Registries.BLOCK).getOptional(ResourceLocation.tryParse(newValue));
|
||||
Optional<Block> ignoredBlock = source.registryAccess().lookupOrThrow(Registries.BLOCK).getOptional(Identifier.tryParse(newValue));
|
||||
if (!ignoredBlock.isPresent()) {
|
||||
Messenger.m(source, "r Unknown block '" + newValue + "'.");
|
||||
return null;
|
||||
@@ -981,48 +1008,6 @@ public class CarpetSettings
|
||||
)
|
||||
public static int sculkSensorRange = 8;
|
||||
|
||||
/**
|
||||
* Listener, we need to update world borders to change whether
|
||||
* they are currently moving in real time or in game time.
|
||||
*/
|
||||
private static class WorldBorderValidator extends Validator<Boolean>
|
||||
{
|
||||
@Override
|
||||
public Boolean validate(CommandSourceStack source, CarpetRule<Boolean> changingRule, Boolean newValue, String userInput)
|
||||
{
|
||||
if (changingRule.value() ^ newValue)
|
||||
{
|
||||
// Needed for the update
|
||||
tickSyncedWorldBorders = newValue;
|
||||
MinecraftServer server = CarpetServer.minecraft_server;
|
||||
if (server == null)
|
||||
{
|
||||
return newValue;
|
||||
}
|
||||
for (ServerLevel level : server.getAllLevels())
|
||||
{
|
||||
WorldBorder worldBorder = level.getWorldBorder();
|
||||
if (worldBorder.getStatus() != BorderStatus.STATIONARY)
|
||||
{
|
||||
double from = worldBorder.getSize();
|
||||
double to = worldBorder.getLerpTarget();
|
||||
long time = worldBorder.getLerpRemainingTime();
|
||||
worldBorder.lerpSizeBetween(from, to, time);
|
||||
}
|
||||
}
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
|
||||
@Rule(
|
||||
desc = "Makes world borders move based on in game time instead of real time",
|
||||
extra = "This has the effect that when the tick rate changes the world border speed also changes proportional to it",
|
||||
category = FEATURE,
|
||||
validate = WorldBorderValidator.class
|
||||
)
|
||||
public static boolean tickSyncedWorldBorders = false;
|
||||
|
||||
public enum FungusGrowthMode {
|
||||
FALSE, RANDOM, ALL;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import carpet.script.Expression;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
@@ -304,7 +305,7 @@ public class SettingsManager {
|
||||
/**
|
||||
* Calling this method is not supported.
|
||||
*/
|
||||
public void inspectClientsideCommand(CommandSourceStack source, String string)
|
||||
public void inspectClientsideCommand(String string)
|
||||
{
|
||||
if (string.startsWith("/" + identifier + " "))
|
||||
{
|
||||
@@ -316,9 +317,9 @@ public class SettingsManager {
|
||||
if (rules.containsKey(rule) && rules.get(rule).canBeToggledClientSide())
|
||||
{
|
||||
try {
|
||||
rules.get(rule).set(source, strOption);
|
||||
rules.get(rule).set(null, strOption);
|
||||
} catch (InvalidRuleValueException e) {
|
||||
e.notifySource(rule, source);
|
||||
//e.notifySource(rule, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -331,7 +332,7 @@ public class SettingsManager {
|
||||
{
|
||||
if (RuleHelper.getBooleanValue(rule) || (rule.type() == String.class && !rule.value().equals("false")))
|
||||
{
|
||||
CarpetServer.scriptServer.addScriptHost(source, rule.scarpetApp, s -> CommandHelper.canUseCommand(s, rule.value()), false, false, true, null);
|
||||
CarpetServer.scriptServer.addScriptHost(source, rule.scarpetApp, s -> CommandHelper.canUseCommand(s, rule.value()), false, false, true, null, Expression.LoadOverride.DEFAULT);
|
||||
} else {
|
||||
CarpetServer.scriptServer.removeScriptHost(source, rule.scarpetApp, false, true);
|
||||
}
|
||||
@@ -694,16 +695,16 @@ public class SettingsManager {
|
||||
{
|
||||
if (locked()) return 0;
|
||||
if (!rules.containsKey(rule.name())) return 0;
|
||||
ConfigReadResult conf = readSettingsFromConf(getFile());
|
||||
conf.ruleMap().put(rule.name(), stringValue);
|
||||
writeSettingsToConf(conf); // this may feels weird, but if conf
|
||||
// is locked, it will never reach this point.
|
||||
try {
|
||||
rule.set(source, stringValue);
|
||||
Messenger.m(source ,"gi "+String.format(tr(TranslationKeys.DEFAULT_SET), RuleHelper.translatedName(rule), stringValue));
|
||||
} catch (InvalidRuleValueException e) {
|
||||
e.notifySource(rule.name(), source);
|
||||
return 0;
|
||||
}
|
||||
ConfigReadResult conf = readSettingsFromConf(getFile());
|
||||
conf.ruleMap().put(rule.name(), stringValue);
|
||||
writeSettingsToConf(conf);
|
||||
return 1;
|
||||
}
|
||||
// removes overrides of the default values in the file
|
||||
|
||||
@@ -241,7 +241,7 @@ public class DrawCommand
|
||||
}
|
||||
if (CarpetSettings.fillUpdates)
|
||||
{
|
||||
list.forEach(blockpos1 -> world.blockUpdated(blockpos1, world.getBlockState(blockpos1).getBlock()));
|
||||
list.forEach(blockpos1 -> world.updateNeighborsAt(blockpos1, world.getBlockState(blockpos1).getBlock()));
|
||||
}
|
||||
Messenger.m(ctx.getSource(), "gi Filled " + affected + " blocks");
|
||||
return affected;
|
||||
@@ -291,7 +291,7 @@ public class DrawCommand
|
||||
|
||||
if (CarpetSettings.fillUpdates)
|
||||
{
|
||||
list.forEach(p -> world.blockUpdated(p, world.getBlockState(p).getBlock()));
|
||||
list.forEach(p -> world.updateNeighborsAt(p, world.getBlockState(p).getBlock()));
|
||||
}
|
||||
|
||||
Messenger.m(source, "gi Filled " + affected + " blocks");
|
||||
@@ -390,7 +390,7 @@ public class DrawCommand
|
||||
|
||||
for (BlockPos blockpos1 : list) {
|
||||
Block blokc = world.getBlockState(blockpos1).getBlock();
|
||||
world.blockUpdated(blockpos1, blokc);
|
||||
world.updateNeighborsAt(blockpos1, blokc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,7 +441,7 @@ public class DrawCommand
|
||||
|
||||
for (BlockPos blockpos1 : list) {
|
||||
Block blokc = world.getBlockState(blockpos1).getBlock();
|
||||
world.blockUpdated(blockpos1, blokc);
|
||||
world.updateNeighborsAt(blockpos1, blokc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ public class InfoCommand
|
||||
|
||||
private static int infoBlock(CommandSourceStack source, BlockPos pos, String grep)
|
||||
{
|
||||
if (!source.hasPermission(Commands.LEVEL_GAMEMASTERS)) {
|
||||
if (!Commands.LEVEL_GAMEMASTERS.check(source.permissions())) {
|
||||
//check id pos is loaded
|
||||
if (!source.getLevel().hasChunkAt(pos)) {
|
||||
Messenger.m(source, "r Chunk is not loaded");
|
||||
|
||||
@@ -15,6 +15,8 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.entity.EntitySpawnRequest;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
|
||||
@@ -39,11 +41,11 @@ public class PerimeterInfoCommand
|
||||
BlockPosArgument.getSpawnablePos(c, "center position"),
|
||||
null)).
|
||||
then(argument("mob", resource(commandBuildContext, Registries.ENTITY_TYPE)).
|
||||
suggests(SuggestionProviders.SUMMONABLE_ENTITIES).
|
||||
suggests(SuggestionProviders.cast(SuggestionProviders.SUMMONABLE_ENTITIES)).
|
||||
executes( (c) -> perimeterDiagnose(
|
||||
c.getSource(),
|
||||
BlockPosArgument.getSpawnablePos(c, "center position"),
|
||||
getSummonableEntityType(c, "mob").key().location().toString()
|
||||
getSummonableEntityType(c, "mob").key().identifier().toString()
|
||||
))));
|
||||
dispatcher.register(command);
|
||||
}
|
||||
@@ -55,8 +57,8 @@ public class PerimeterInfoCommand
|
||||
if (mobId != null)
|
||||
{
|
||||
nbttagcompound.putString("id", mobId);
|
||||
Entity baseEntity = EntityType.loadEntityRecursive(nbttagcompound, source.getLevel(), (entity_1x) -> {
|
||||
entity_1x.moveTo(new BlockPos(pos.getX(), source.getLevel().getMinBuildHeight()-10, pos.getZ()), entity_1x.getYRot(), entity_1x. getXRot());
|
||||
Entity baseEntity = EntityType.loadEntityRecursive(nbttagcompound, source.getLevel(), new EntitySpawnRequest(EntitySpawnReason.COMMAND, true), (entity_1x) -> {
|
||||
entity_1x.snapTo(new BlockPos(pos.getX(), source.getLevel().getMinY()-10, pos.getZ()), entity_1x.getYRot(), entity_1x. getXRot());
|
||||
return !source.getLevel().addWithUUID(entity_1x) ? null : entity_1x;
|
||||
});
|
||||
if (!(baseEntity instanceof Mob))
|
||||
|
||||
@@ -20,6 +20,7 @@ import me.lucko.fabric.api.permissions.v0.Permissions;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.commands.CommandBuildContext;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.Commands;
|
||||
import net.minecraft.commands.arguments.DimensionArgument;
|
||||
import net.minecraft.commands.arguments.GameModeArgument;
|
||||
import net.minecraft.commands.arguments.coordinates.RotationArgument;
|
||||
@@ -30,6 +31,8 @@ import net.minecraft.core.UUIDUtil;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.players.NameAndId;
|
||||
import net.minecraft.server.players.OldUsersConverter;
|
||||
import net.minecraft.server.players.PlayerList;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.GameType;
|
||||
@@ -37,19 +40,18 @@ import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static net.minecraft.commands.Commands.argument;
|
||||
import static net.minecraft.commands.Commands.literal;
|
||||
import static net.minecraft.commands.SharedSuggestionProvider.suggest;
|
||||
|
||||
public class PlayerCommand {
|
||||
public class PlayerCommand
|
||||
{
|
||||
// TODO: allow any order like execute
|
||||
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext) {
|
||||
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext)
|
||||
{
|
||||
LiteralArgumentBuilder<CommandSourceStack> command = literal("player")
|
||||
.requires((player) -> Permissions.check(player, "carpet.command.player", CommandHelper.canUseCommand(player, CarpetSettings.commandPlayer)))
|
||||
.then(argument("player", StringArgumentType.word())
|
||||
@@ -67,7 +69,7 @@ public class PlayerCommand {
|
||||
.then(argument("slot", IntegerArgumentType.integer(1, 9))
|
||||
.executes(c -> manipulate(c, ap -> ap.setSlot(IntegerArgumentType.getInteger(c, "slot"))))))
|
||||
.then(literal("kill").executes(PlayerCommand::kill))
|
||||
.then(literal("shadow").executes(PlayerCommand::shadow))
|
||||
.then(literal("shadow"). executes(PlayerCommand::shadow))
|
||||
.then(literal("mount").executes(manipulation(ap -> ap.mount(true)))
|
||||
.then(literal("anything").executes(manipulation(ap -> ap.mount(false)))))
|
||||
.then(literal("dismount").executes(manipulation(EntityPlayerActionPack::dismount)))
|
||||
@@ -98,26 +100,28 @@ public class PlayerCommand {
|
||||
.then(literal("left").executes(manipulation(ap -> ap.setStrafing(1))))
|
||||
.then(literal("right").executes(manipulation(ap -> ap.setStrafing(-1))))
|
||||
).then(literal("spawn").executes(PlayerCommand::spawn)
|
||||
.then(literal("in").requires((player) -> Permissions.check(player, "carpet.command.player.gamemode", player.hasPermission(2)))
|
||||
.then(literal("in").requires((player) -> Permissions.check(player, "carpet.command.player.gamemode", Commands.LEVEL_GAMEMASTERS.check(player.permissions())))
|
||||
.then(argument("gamemode", GameModeArgument.gameMode())
|
||||
.executes(PlayerCommand::spawn)))
|
||||
.executes(PlayerCommand::spawn)))
|
||||
.then(literal("at").then(argument("position", Vec3Argument.vec3()).executes(PlayerCommand::spawn)
|
||||
.then(literal("facing").then(argument("direction", RotationArgument.rotation()).executes(PlayerCommand::spawn)
|
||||
.then(literal("in")
|
||||
.requires((player) -> Permissions.check(player,"carpet.command.player.dimension",player.hasPermission(4)))
|
||||
.then(argument("dimension", DimensionArgument.dimension()).executes(PlayerCommand::spawn)
|
||||
.then(literal("in").requires((player) -> player.hasPermission(2))
|
||||
.then(argument("dimension", DimensionArgument.dimension())
|
||||
.requires((player) -> Permissions.check(player,"carpet.command.player.dimension",Commands.LEVEL_GAMEMASTERS.check(player.permissions())))
|
||||
.executes(PlayerCommand::spawn)
|
||||
.then(literal("in")
|
||||
.then(argument("gamemode", GameModeArgument.gameMode())
|
||||
.executes(PlayerCommand::spawn)
|
||||
)))
|
||||
)))
|
||||
.executes(PlayerCommand::spawn)
|
||||
)))
|
||||
)))
|
||||
))
|
||||
)
|
||||
);
|
||||
dispatcher.register(command);
|
||||
}
|
||||
|
||||
private static LiteralArgumentBuilder<CommandSourceStack> makeActionCommand(String actionName, ActionType type) {
|
||||
private static LiteralArgumentBuilder<CommandSourceStack> makeActionCommand(String actionName, ActionType type)
|
||||
{
|
||||
return literal(actionName)
|
||||
.executes(manipulation(ap -> ap.start(type, Action.once())))
|
||||
.then(literal("once").executes(manipulation(ap -> ap.start(type, Action.once()))))
|
||||
@@ -126,7 +130,8 @@ public class PlayerCommand {
|
||||
.executes(c -> manipulate(c, ap -> ap.start(type, Action.interval(IntegerArgumentType.getInteger(c, "ticks")))))));
|
||||
}
|
||||
|
||||
private static LiteralArgumentBuilder<CommandSourceStack> makeDropCommand(String actionName, boolean dropAll) {
|
||||
private static LiteralArgumentBuilder<CommandSourceStack> makeDropCommand(String actionName, boolean dropAll)
|
||||
{
|
||||
return literal(actionName)
|
||||
.then(literal("all").executes(manipulation(ap -> ap.drop(-2, dropAll))))
|
||||
.then(literal("mainhand").executes(manipulation(ap -> ap.drop(-1, dropAll))))
|
||||
@@ -135,32 +140,39 @@ public class PlayerCommand {
|
||||
executes(c -> manipulate(c, ap -> ap.drop(IntegerArgumentType.getInteger(c, "slot"), dropAll))));
|
||||
}
|
||||
|
||||
private static Collection<String> getPlayerSuggestions(CommandSourceStack source) {
|
||||
Set<String> players = new LinkedHashSet<>(List.of("Steve.bot", "Alex.bot"));
|
||||
private static Collection<String> getPlayerSuggestions(CommandSourceStack source)
|
||||
{
|
||||
Set<String> players = new LinkedHashSet<>(List.of("Steve", "Alex"));
|
||||
players.addAll(source.getOnlinePlayerNames());
|
||||
return players;
|
||||
}
|
||||
|
||||
private static ServerPlayer getPlayer(CommandContext<CommandSourceStack> context) {
|
||||
private static ServerPlayer getPlayer(CommandContext<CommandSourceStack> context)
|
||||
{
|
||||
String playerName = StringArgumentType.getString(context, "player");
|
||||
MinecraftServer server = context.getSource().getServer();
|
||||
return server.getPlayerList().getPlayerByName(playerName);
|
||||
}
|
||||
|
||||
private static boolean cantManipulate(CommandContext<CommandSourceStack> context) {
|
||||
private static boolean cantManipulate(CommandContext<CommandSourceStack> context)
|
||||
{
|
||||
Player player = getPlayer(context);
|
||||
CommandSourceStack source = context.getSource();
|
||||
if (player == null) {
|
||||
if (player == null)
|
||||
{
|
||||
Messenger.m(source, "r Can only manipulate existing players");
|
||||
return true;
|
||||
}
|
||||
Player sender = source.getPlayer();
|
||||
if (sender == null) {
|
||||
if (sender == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!source.getServer().getPlayerList().isOp(sender.getGameProfile())) {
|
||||
if (sender != player && !(player instanceof EntityPlayerMPFake)) {
|
||||
if (!source.getServer().getPlayerList().isOp(sender.nameAndId()))
|
||||
{
|
||||
if (sender != player && !(player instanceof EntityPlayerMPFake))
|
||||
{
|
||||
Messenger.m(source, "r Non OP players can't control other real players");
|
||||
return true;
|
||||
}
|
||||
@@ -168,7 +180,8 @@ public class PlayerCommand {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean cantReMove(CommandContext<CommandSourceStack> context) {
|
||||
private static boolean cantReMove(CommandContext<CommandSourceStack> context)
|
||||
{
|
||||
if (cantManipulate(context)) return true;
|
||||
Player player = getPlayer(context);
|
||||
if (player instanceof EntityPlayerMPFake) return false;
|
||||
@@ -176,63 +189,95 @@ public class PlayerCommand {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean cantSpawn(CommandContext<CommandSourceStack> context) {
|
||||
private static boolean cantSpawn(CommandContext<CommandSourceStack> context)
|
||||
{
|
||||
String playerName = StringArgumentType.getString(context, "player");
|
||||
MinecraftServer server = context.getSource().getServer();
|
||||
PlayerList manager = server.getPlayerList();
|
||||
|
||||
if (manager.getPlayerByName(playerName) != null) {
|
||||
if (EntityPlayerMPFake.isSpawningPlayer(playerName))
|
||||
{
|
||||
Messenger.m(context.getSource(), "r Player ", "rb " + playerName, "r is currently logging on");
|
||||
return true;
|
||||
}
|
||||
if (manager.getPlayerByName(playerName) != null)
|
||||
{
|
||||
Messenger.m(context.getSource(), "r Player ", "rb " + playerName, "r is already logged on");
|
||||
return true;
|
||||
}
|
||||
var sender = context.getSource().getPlayer();
|
||||
if(!playerName.endsWith(".bot") && sender != null && !Permissions.check(sender,"carpet.command.player.name",sender.hasPermissions(4))){
|
||||
if(!playerName.endsWith(".bot") && sender != null && !Permissions.check(sender,"carpet.command.player.name",Commands.LEVEL_GAMEMASTERS.check(sender.permissions()))){
|
||||
Messenger.m(sender,"r You can't spawn a player whose name isn't ends with `.bot` suffix.");
|
||||
Messenger.m(sender,"r Try this: /player "+playerName+".bot spawn ...");
|
||||
return true;
|
||||
}
|
||||
|
||||
GameProfile profile = server.getProfileCache().get(playerName).orElse(null);
|
||||
if (profile == null) {
|
||||
if (!CarpetSettings.allowSpawningOfflinePlayers) {
|
||||
Messenger.m(context.getSource(), "r Player " + playerName + " is either banned by Mojang, or auth servers are down. " +
|
||||
UUID uuid = OldUsersConverter.convertMobOwnerIfNecessary(server, playerName);
|
||||
if (uuid == null)
|
||||
{
|
||||
if (!CarpetSettings.allowSpawningOfflinePlayers)
|
||||
{
|
||||
Messenger.m(context.getSource(), "r Player "+playerName+" is either banned by Mojang, or auth servers are down. " +
|
||||
"Banned players can only be summoned in Singleplayer and in servers in off-line mode.");
|
||||
return true;
|
||||
} else {
|
||||
profile = new GameProfile(UUIDUtil.createOfflinePlayerUUID(playerName), playerName);
|
||||
uuid = UUIDUtil.createOfflinePlayerUUID(playerName);
|
||||
}
|
||||
}
|
||||
if (manager.getBans().isBanned(profile)) {
|
||||
//GameProfile profile = new GameProfile(uuid, playerName);
|
||||
NameAndId profile = server.services().nameToIdCache().get(uuid).orElse(null);
|
||||
if (profile == null)
|
||||
{
|
||||
if (!CarpetSettings.allowSpawningOfflinePlayers)
|
||||
{
|
||||
Messenger.m(context.getSource(), "r Player "+playerName+" is either banned by Mojang, or auth servers are down. " +
|
||||
"Banned players can only be summoned in Singleplayer and in servers in off-line mode.");
|
||||
return true;
|
||||
} else {
|
||||
profile = new NameAndId(UUIDUtil.createOfflinePlayerUUID(playerName), playerName);
|
||||
}
|
||||
}
|
||||
if (manager.getBans().isBanned(profile))
|
||||
{
|
||||
Messenger.m(context.getSource(), "r Player ", "rb " + playerName, "r is banned on this server");
|
||||
return true;
|
||||
}
|
||||
if (manager.isUsingWhitelist() && manager.isWhiteListed(profile) && !context.getSource().hasPermission(2)) {
|
||||
if (manager.isUsingWhitelist() && manager.isWhiteListed(profile) && !Commands.LEVEL_GAMEMASTERS.check(context.getSource().permissions()))
|
||||
{
|
||||
Messenger.m(context.getSource(), "r Whitelisted players can only be spawned by operators");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int kill(CommandContext<CommandSourceStack> context) {
|
||||
private static int kill(CommandContext<CommandSourceStack> context)
|
||||
{
|
||||
if (cantReMove(context)) return 0;
|
||||
getPlayer(context).kill();
|
||||
ServerPlayer player = getPlayer(context);
|
||||
player.kill(player.level());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface SupplierWithCSE<T> {
|
||||
interface SupplierWithCSE<T>
|
||||
{
|
||||
T get() throws CommandSyntaxException;
|
||||
}
|
||||
|
||||
private static <T> T getArgOrDefault(SupplierWithCSE<T> getter, T defaultValue) throws CommandSyntaxException {
|
||||
try {
|
||||
private static <T> T getArgOrDefault(SupplierWithCSE<T> getter, T defaultValue) throws CommandSyntaxException
|
||||
{
|
||||
try
|
||||
{
|
||||
return getter.get();
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
private static int spawn(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
|
||||
private static int spawn(CommandContext<CommandSourceStack> context) throws CommandSyntaxException
|
||||
{
|
||||
if (cantSpawn(context)) return 0;
|
||||
|
||||
CommandSourceStack source = context.getSource();
|
||||
@@ -250,29 +295,33 @@ public class PlayerCommand {
|
||||
);
|
||||
GameType mode = GameType.CREATIVE;
|
||||
boolean flying = false;
|
||||
if (source.getEntity() instanceof ServerPlayer sender) {
|
||||
if (source.getEntity() instanceof ServerPlayer sender)
|
||||
{
|
||||
mode = sender.gameMode.getGameModeForPlayer();
|
||||
flying = sender.getAbilities().flying;
|
||||
}
|
||||
try {
|
||||
mode = GameModeArgument.getGameMode(context, "gamemode");
|
||||
} catch (IllegalArgumentException notPresent) {
|
||||
}
|
||||
} catch (IllegalArgumentException notPresent) {}
|
||||
|
||||
if (mode == GameType.SPECTATOR) {
|
||||
if (mode == GameType.SPECTATOR)
|
||||
{
|
||||
// Force override flying to true for spectator players, or they will fell out of the world.
|
||||
flying = true;
|
||||
} else if (mode.isSurvival()) {
|
||||
} else if (mode.isSurvival())
|
||||
{
|
||||
// Force override flying to false for survival-like players, or they will fly too
|
||||
flying = false;
|
||||
}
|
||||
String playerName = StringArgumentType.getString(context, "player");
|
||||
if (playerName.length() > maxNameLength(source.getServer())) {
|
||||
if (playerName.length() > maxNameLength(source.getServer()))
|
||||
{
|
||||
Messenger.m(source, "rb Player name: " + playerName + " is too long");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!Level.isInSpawnableBounds(BlockPos.containing(pos))) {
|
||||
if (!Level.isInSpawnableBounds(BlockPos.containing(pos)))
|
||||
{
|
||||
Messenger.m(source, "rb Player " + playerName + " cannot be placed outside of the world");
|
||||
return 0;
|
||||
}
|
||||
@@ -281,40 +330,44 @@ public class PlayerCommand {
|
||||
Messenger.m(source, "rb Player " + playerName + " doesn't exist and cannot spawn in online mode. " +
|
||||
"Turn the server offline or the allowSpawningOfflinePlayers on to spawn non-existing players");
|
||||
return 0;
|
||||
}
|
||||
;
|
||||
};
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int maxNameLength(MinecraftServer server) {
|
||||
private static int maxNameLength(MinecraftServer server)
|
||||
{
|
||||
return server.getPort() >= 0 ? SharedConstants.MAX_PLAYER_NAME_LENGTH : 40;
|
||||
}
|
||||
|
||||
private static int manipulate(CommandContext<CommandSourceStack> context, Consumer<EntityPlayerActionPack> action) {
|
||||
private static int manipulate(CommandContext<CommandSourceStack> context, Consumer<EntityPlayerActionPack> action)
|
||||
{
|
||||
if (cantManipulate(context)) return 0;
|
||||
ServerPlayer player = getPlayer(context);
|
||||
action.accept(((ServerPlayerInterface) player).getActionPack());
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static Command<CommandSourceStack> manipulation(Consumer<EntityPlayerActionPack> action) {
|
||||
private static Command<CommandSourceStack> manipulation(Consumer<EntityPlayerActionPack> action)
|
||||
{
|
||||
return c -> manipulate(c, action);
|
||||
}
|
||||
|
||||
private static int shadow(CommandContext<CommandSourceStack> context) {
|
||||
private static int shadow(CommandContext<CommandSourceStack> context)
|
||||
{
|
||||
if (cantManipulate(context)) return 0;
|
||||
|
||||
ServerPlayer player = getPlayer(context);
|
||||
if (player instanceof EntityPlayerMPFake) {
|
||||
if (player instanceof EntityPlayerMPFake)
|
||||
{
|
||||
Messenger.m(context.getSource(), "r Cannot shadow fake players");
|
||||
return 0;
|
||||
}
|
||||
if (player.getServer().isSingleplayerOwner(player.getGameProfile())) {
|
||||
if (player.level().getServer().isSingleplayerOwner(player.nameAndId())) {
|
||||
Messenger.m(context.getSource(), "r Cannot shadow single-player server owner");
|
||||
return 0;
|
||||
}
|
||||
|
||||
EntityPlayerMPFake.createShadow(player.server, player);
|
||||
EntityPlayerMPFake.createShadow(player.level().getServer(), player);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
|
||||
import net.minecraft.world.entity.ai.memory.MemorySlot;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface BrainInterface {
|
||||
Map<MemoryModuleType<?>, MemorySlot<?>> getMemoriesCM();
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
import net.minecraft.server.level.Ticket;
|
||||
import net.minecraft.util.SortedArraySet;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
|
||||
public interface ChunkTicketManagerInterface
|
||||
{
|
||||
void changeSpawnChunks(ChunkPos pos, int distance);
|
||||
|
||||
Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> getTicketsByPosition();
|
||||
|
||||
void replaceHolder(ChunkHolder oldHolder, ChunkHolder newHolder);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import net.minecraft.commands.CommandResultCallback;
|
||||
import net.minecraft.commands.CommandSigningContext;
|
||||
import net.minecraft.commands.arguments.EntityAnchorArgument;
|
||||
import net.minecraft.util.TaskChainer;
|
||||
|
||||
public interface CommandSourceStackInterface {
|
||||
void setupPrivates(boolean bl, CommandResultCallback commandResultCallback, EntityAnchorArgument.Anchor anchor, CommandSigningContext commandSigningContext, TaskChainer taskChainer);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
|
||||
public interface DefaultRedstoneWireEvaluatorInferface
|
||||
{
|
||||
int calculateTargetStrengthCM(final Level level, final BlockPos pos);
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import carpet.script.EntityEventsGroup;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
||||
public interface EntityInterface
|
||||
{
|
||||
@@ -19,4 +22,5 @@ public interface EntityInterface
|
||||
int getPublicNetherPortalCooldown();
|
||||
void setPublicNetherPortalCooldown(int what);
|
||||
|
||||
Stream<Entity> cm$getIndirectPassengersStream();
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package carpet.fakes;
|
||||
|
||||
public interface FoodDataInterface
|
||||
{
|
||||
float getCMExhaustionLevel();
|
||||
|
||||
void setExhaustion(float aFloat);
|
||||
}
|
||||
@@ -10,5 +10,5 @@ public interface IngredientInterface
|
||||
* Gets all the stacks of the ingredients for a given item recipe. Also used for {@link carpet.helpers.HopperCounter#guessColor}
|
||||
* to guess the colour of an item to display it prettily
|
||||
*/
|
||||
List<Collection<ItemStack>> getRecipeStacks();
|
||||
//List<Collection<ItemStack>> getRecipeStacks();
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import net.minecraft.world.level.redstone.CollectingNeighborUpdater;
|
||||
import net.minecraft.world.level.redstone.NeighborUpdater;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -21,5 +22,5 @@ public interface LevelInterface
|
||||
|
||||
List<Entity> getOtherEntitiesLimited(@Nullable Entity except, AABB box, Predicate<? super Entity> predicate, int limit);
|
||||
|
||||
NeighborUpdater getNeighborUpdater();
|
||||
CollectingNeighborUpdater getNeighborUpdater();
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState;
|
||||
|
||||
public interface PistonHeadRenderStateInterface {
|
||||
public BlockEntityRenderState getMovedBERenderState();
|
||||
public void setMovedBERenderState(BlockEntityRenderState state);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
|
||||
public interface RecipeManagerInterface
|
||||
{
|
||||
/**
|
||||
* Gets all the recipes for a given item. Also used for {@link carpet.helpers.HopperCounter#guessColor} to guess the
|
||||
* colour of an item to display it prettily
|
||||
*/
|
||||
List<Recipe<?>> getAllMatching(final RecipeType<?> type, final ResourceLocation itemId, final RegistryAccess registryAccess);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.entity.LevelEntityGetter;
|
||||
import net.minecraft.world.level.storage.ServerLevelData;
|
||||
|
||||
public interface ServerWorldInterface {
|
||||
ServerLevelData getWorldPropertiesCM();
|
||||
LevelEntityGetter<Entity> getEntityLookupCMPublic();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import net.minecraft.server.level.Ticket;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface TicketsFetcherInterface
|
||||
{
|
||||
Long2ObjectOpenHashMap<List<Ticket>> getTicketsByPosition();
|
||||
}
|
||||
@@ -6,5 +6,5 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public interface WorldChunkInterface
|
||||
{
|
||||
BlockState setBlockStateWithBlockEntity(BlockPos blockPos, BlockState newBlockState, BlockEntity newBlockEntity, boolean boolean1);
|
||||
BlockState setBlockStateWithBlockEntity(BlockPos blockPos, BlockState newBlockState, BlockEntity newBlockEntity, int flags);
|
||||
}
|
||||
@@ -100,7 +100,7 @@ public class BlockRotator
|
||||
}
|
||||
}
|
||||
// Send block update to the block that just have been rotated.
|
||||
world.neighborChanged(blockpos, block, source.pos());
|
||||
world.neighborChanged(blockpos, block, null);
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import carpet.script.utils.Tracer;
|
||||
import net.minecraft.commands.arguments.EntityAnchorArgument;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetHeldSlotPacket;
|
||||
import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
@@ -19,11 +19,11 @@ import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.animal.horse.AbstractHorse;
|
||||
import net.minecraft.world.entity.animal.equine.AbstractHorse;
|
||||
import net.minecraft.world.entity.decoration.ItemFrame;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.vehicle.Boat;
|
||||
import net.minecraft.world.entity.vehicle.Minecart;
|
||||
import net.minecraft.world.entity.vehicle.boat.Boat;
|
||||
import net.minecraft.world.entity.vehicle.minecart.Minecart;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
@@ -201,7 +201,7 @@ public class EntityPlayerActionPack
|
||||
if (closest instanceof AbstractHorse && onlyRideables)
|
||||
((AbstractHorse) closest).mobInteract(player, InteractionHand.MAIN_HAND);
|
||||
else
|
||||
player.startRiding(closest,true);
|
||||
player.startRiding(closest,true, true);
|
||||
return this;
|
||||
}
|
||||
public EntityPlayerActionPack dismount()
|
||||
@@ -274,15 +274,15 @@ public class EntityPlayerActionPack
|
||||
else // one slot
|
||||
{
|
||||
if (selectedSlot == -1)
|
||||
selectedSlot = inv.selected;
|
||||
selectedSlot = inv.getSelectedSlot();
|
||||
dropItemFromSlot(selectedSlot, dropAll);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSlot(int slot)
|
||||
{
|
||||
player.getInventory().selected = slot-1;
|
||||
player.connection.send(new ClientboundSetCarriedItemPacket(slot-1));
|
||||
player.getInventory().setSelectedSlot(slot-1);
|
||||
player.connection.send(new ClientboundSetHeldSlotPacket(slot-1));
|
||||
}
|
||||
|
||||
public enum ActionType
|
||||
@@ -310,16 +310,16 @@ public class EntityPlayerActionPack
|
||||
case BLOCK:
|
||||
{
|
||||
player.resetLastActionTime();
|
||||
ServerLevel world = player.serverLevel();
|
||||
ServerLevel world = player.level();
|
||||
BlockHitResult blockHit = (BlockHitResult) hit;
|
||||
BlockPos pos = blockHit.getBlockPos();
|
||||
Direction side = blockHit.getDirection();
|
||||
if (pos.getY() < player.level().getMaxBuildHeight() - (side == Direction.UP ? 1 : 0) && world.mayInteract(player, pos))
|
||||
if (pos.getY() < player.level().getMaxY() - (side == Direction.UP ? 1 : 0) && world.mayInteract(player, pos))
|
||||
{
|
||||
InteractionResult result = player.gameMode.useItemOn(player, world, player.getItemInHand(hand), hand, blockHit);
|
||||
if (result.consumesAction())
|
||||
if (result instanceof InteractionResult.Success success)
|
||||
{
|
||||
if (result.shouldSwing()) player.swing(hand);
|
||||
if (success.swingSource() == InteractionResult.SwingSource.SERVER) player.swing(hand);
|
||||
ap.itemUseCooldown = 3;
|
||||
return true;
|
||||
}
|
||||
@@ -334,13 +334,13 @@ public class EntityPlayerActionPack
|
||||
boolean handWasEmpty = player.getItemInHand(hand).isEmpty();
|
||||
boolean itemFrameEmpty = (entity instanceof ItemFrame) && ((ItemFrame) entity).getItem().isEmpty();
|
||||
Vec3 relativeHitPos = entityHit.getLocation().subtract(entity.getX(), entity.getY(), entity.getZ());
|
||||
if (entity.interactAt(player, relativeHitPos, hand).consumesAction())
|
||||
if (entity.interact(player, hand, relativeHitPos).consumesAction())
|
||||
{
|
||||
ap.itemUseCooldown = 3;
|
||||
return true;
|
||||
}
|
||||
// fix for SS itemframe always returns CONSUME even if no action is performed
|
||||
if (player.interactOn(entity, hand).consumesAction() && !(handWasEmpty && itemFrameEmpty))
|
||||
if (player.interactOn(entity, hand, relativeHitPos).consumesAction() && !(handWasEmpty && itemFrameEmpty))
|
||||
{
|
||||
ap.itemUseCooldown = 3;
|
||||
return true;
|
||||
@@ -402,7 +402,7 @@ public class EntityPlayerActionPack
|
||||
boolean blockBroken = false;
|
||||
if (player.gameMode.getGameModeForPlayer().isCreative())
|
||||
{
|
||||
player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, side, player.level().getMaxBuildHeight(), -1);
|
||||
player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, side, player.level().getMaxY(), -1);
|
||||
ap.blockHitDelay = 5;
|
||||
blockBroken = true;
|
||||
}
|
||||
@@ -410,9 +410,9 @@ public class EntityPlayerActionPack
|
||||
{
|
||||
if (ap.currentBlock != null)
|
||||
{
|
||||
player.gameMode.handleBlockBreakAction(ap.currentBlock, ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, side, player.level().getMaxBuildHeight(), -1);
|
||||
player.gameMode.handleBlockBreakAction(ap.currentBlock, ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, side, player.level().getMaxY(), -1);
|
||||
}
|
||||
player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, side, player.level().getMaxBuildHeight(), -1);
|
||||
player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, side, player.level().getMaxY(), -1);
|
||||
boolean notAir = !state.isAir();
|
||||
if (notAir && ap.curBlockDamageMP == 0)
|
||||
{
|
||||
@@ -435,7 +435,7 @@ public class EntityPlayerActionPack
|
||||
ap.curBlockDamageMP += state.getDestroyProgress(player, player.level(), pos);
|
||||
if (ap.curBlockDamageMP >= 1)
|
||||
{
|
||||
player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.STOP_DESTROY_BLOCK, side, player.level().getMaxBuildHeight(), -1);
|
||||
player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.STOP_DESTROY_BLOCK, side, player.level().getMaxY(), -1);
|
||||
ap.currentBlock = null;
|
||||
ap.blockHitDelay = 5;
|
||||
blockBroken = true;
|
||||
@@ -457,7 +457,7 @@ public class EntityPlayerActionPack
|
||||
EntityPlayerActionPack ap = ((ServerPlayerInterface) player).getActionPack();
|
||||
if (ap.currentBlock == null) return;
|
||||
player.level().destroyBlockProgress(-1, ap.currentBlock, -1);
|
||||
player.gameMode.handleBlockBreakAction(ap.currentBlock, ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, Direction.DOWN, player.level().getMaxBuildHeight(), -1);
|
||||
player.gameMode.handleBlockBreakAction(ap.currentBlock, ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, Direction.DOWN, player.level().getMaxY(), -1);
|
||||
ap.currentBlock = null;
|
||||
}
|
||||
},
|
||||
@@ -468,7 +468,8 @@ public class EntityPlayerActionPack
|
||||
{
|
||||
if (action.limit == 1)
|
||||
{
|
||||
if (player.onGround()) player.jumpFromGround(); // onGround
|
||||
if (player.onGround()) player.jumpFromGround();
|
||||
else if (!player.onClimbable()) player.tryToStartFallFlying();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -58,7 +58,7 @@ public interface FertilizableCoral extends BonemealableBlock {
|
||||
|
||||
MapColor color = blockUnder.getMapColor(worldIn, pos);
|
||||
BlockState properBlock = blockUnder;
|
||||
HolderSet.Named<Block> coralBlocks = worldIn.registryAccess().registryOrThrow(Registries.BLOCK).getTag(BlockTags.CORAL_BLOCKS).orElseThrow();
|
||||
HolderSet.Named<Block> coralBlocks = worldIn.registryAccess().lookupOrThrow(Registries.BLOCK).get(BlockTags.CORAL_BLOCKS).orElseThrow();
|
||||
for (Holder<Block> block: coralBlocks)
|
||||
{
|
||||
properBlock = block.value().defaultBlockState();
|
||||
@@ -75,10 +75,10 @@ public interface FertilizableCoral extends BonemealableBlock {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (worldIn.random.nextInt(10) == 0)
|
||||
if (worldIn.getRandom().nextInt(10) == 0)
|
||||
{
|
||||
BlockPos randomPos = pos.offset(worldIn.random.nextInt(16) - 8, worldIn.random.nextInt(8), worldIn.random.nextInt(16) - 8);
|
||||
if (coralBlocks.contains(worldIn.getBlockState(randomPos).getBlockHolder()))
|
||||
BlockPos randomPos = pos.offset(worldIn.getRandom().nextInt(16) - 8, worldIn.getRandom().nextInt(8), worldIn.getRandom().nextInt(16) - 8);
|
||||
if (worldIn.getBlockState(randomPos).is(BlockTags.CORAL_BLOCKS))
|
||||
{
|
||||
worldIn.setBlock(randomPos, Blocks.WET_SPONGE.defaultBlockState(), Block.UPDATE_ALL);
|
||||
}
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
package carpet.helpers;
|
||||
|
||||
import carpet.CarpetServer;
|
||||
import carpet.fakes.IngredientInterface;
|
||||
import carpet.fakes.RecipeManagerInterface;
|
||||
import carpet.script.utils.RecipeHelper;
|
||||
import carpet.utils.Messenger;
|
||||
import it.unimi.dsi.fastutil.objects.Object2LongLinkedOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2LongMap;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.network.chat.TextColor;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
@@ -24,7 +25,7 @@ import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.AbstractBannerBlock;
|
||||
import net.minecraft.world.level.block.BeaconBeamBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
@@ -32,12 +33,12 @@ import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.material.MapColor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
@@ -100,9 +101,11 @@ public class HopperCounter
|
||||
{
|
||||
startTick = -1;
|
||||
this.color = color;
|
||||
String hexColor = Integer.toHexString(color.getTextColor());
|
||||
String hexColor = Integer.toHexString(color.getTextColor() & 0xFFFFFF); // don't get alpha
|
||||
if (hexColor.length() < 6)
|
||||
{
|
||||
hexColor = "0".repeat(6 - hexColor.length()) + hexColor;
|
||||
}
|
||||
this.coloredName = '#' + hexColor + ' ' + color.getName();
|
||||
}
|
||||
|
||||
@@ -136,6 +139,7 @@ public class HopperCounter
|
||||
|
||||
/**
|
||||
* Resets all counters, clearing their items.
|
||||
*
|
||||
* @param fresh Whether or not to start the clocks going immediately or later.
|
||||
*/
|
||||
public static void resetAll(MinecraftServer server, boolean fresh)
|
||||
@@ -143,7 +147,10 @@ public class HopperCounter
|
||||
for (HopperCounter counter : COUNTERS.values())
|
||||
{
|
||||
counter.reset(server);
|
||||
if (fresh) counter.startTick = -1;
|
||||
if (fresh)
|
||||
{
|
||||
counter.startTick = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +166,10 @@ public class HopperCounter
|
||||
List<Component> temp = counter.format(server, realtime, false);
|
||||
if (temp.size() > 1)
|
||||
{
|
||||
if (!text.isEmpty()) text.add(Messenger.s(""));
|
||||
if (!text.isEmpty())
|
||||
{
|
||||
text.add(Messenger.s(""));
|
||||
}
|
||||
text.addAll(temp);
|
||||
}
|
||||
}
|
||||
@@ -181,7 +191,7 @@ public class HopperCounter
|
||||
{
|
||||
if (brief)
|
||||
{
|
||||
return Collections.singletonList(Messenger.c("b"+coloredName,"w : ","gi -, -/h, - min "));
|
||||
return Collections.singletonList(Messenger.c("b" + coloredName, "w : ", "gi -, -/h, - min "));
|
||||
}
|
||||
return Collections.singletonList(Messenger.c(coloredName, "w hasn't started counting yet"));
|
||||
}
|
||||
@@ -190,36 +200,36 @@ public class HopperCounter
|
||||
{
|
||||
if (brief)
|
||||
{
|
||||
return Collections.singletonList(Messenger.c("b"+coloredName,"w : ","wb 0","w , ","wb 0","w /h, ", String.format("wb %.1f ", ticks / (20.0 * 60.0)), "w min"));
|
||||
return Collections.singletonList(Messenger.c("b" + coloredName, "w : ", "wb 0", "w , ", "wb 0", "w /h, ", String.format("wb %.1f ", ticks / (20.0 * 60.0)), "w min"));
|
||||
}
|
||||
return Collections.singletonList(Messenger.c("w No items for ", coloredName, String.format("w yet (%.2f min.%s)",
|
||||
ticks / (20.0 * 60.0), (realTime ? " - real time" : "")),
|
||||
"nb [X]", "^g reset", "!/counter " + color.getName() +" reset"));
|
||||
ticks / (20.0 * 60.0), (realTime ? " - real time" : "")),
|
||||
"nb [X]", "^g reset", "!/counter " + color.getName() + " reset"));
|
||||
}
|
||||
if (brief)
|
||||
{
|
||||
return Collections.singletonList(Messenger.c("b"+coloredName,"w : ",
|
||||
"wb "+total,"w , ",
|
||||
"wb "+(total * (20 * 60 * 60) / ticks),"w /h, ",
|
||||
return Collections.singletonList(Messenger.c("b" + coloredName, "w : ",
|
||||
"wb " + total, "w , ",
|
||||
"wb " + (total * (20 * 60 * 60) / ticks), "w /h, ",
|
||||
String.format("wb %.1f ", ticks / (20.0 * 60.0)), "w min"
|
||||
));
|
||||
}
|
||||
List<Component> items = new ArrayList<>();
|
||||
items.add(Messenger.c("w Items for ", coloredName,
|
||||
"w (",String.format("wb %.2f", ticks*1.0/(20*60)), "w min"+(realTime?" - real time":"")+"), ",
|
||||
"w total: ", "wb "+total, "w , (",String.format("wb %.1f",total*1.0*(20*60*60)/ticks),"w /h):",
|
||||
"nb [X]", "^g reset", "!/counter "+color+" reset"
|
||||
"w (", String.format("wb %.2f", ticks * 1.0 / (20 * 60)), "w min" + (realTime ? " - real time" : "") + "), ",
|
||||
"w total: ", "wb " + total, "w , (", String.format("wb %.1f", total * 1.0 * (20 * 60 * 60) / ticks), "w /h):",
|
||||
"nb [X]", "^g reset", "!/counter " + color + " reset"
|
||||
));
|
||||
items.addAll(counter.object2LongEntrySet().stream().sorted((e, f) -> Long.compare(f.getLongValue(), e.getLongValue())).map(e ->
|
||||
{
|
||||
Item item = e.getKey();
|
||||
MutableComponent itemName = Component.translatable(item.getDescriptionId());
|
||||
Style itemStyle = itemName.getStyle();
|
||||
TextColor color = guessColor(item, server.registryAccess());
|
||||
TextColor color = guessColor(item, server.overworld());
|
||||
itemName.setStyle((color != null) ? itemStyle.withColor(color) : itemStyle.withItalic(true));
|
||||
long count = e.getLongValue();
|
||||
return Messenger.c("g - ", itemName,
|
||||
"g : ","wb "+count,"g , ",
|
||||
"g : ", "wb " + count, "g , ",
|
||||
String.format("wb %.1f", count * (20.0 * 60.0 * 60.0) / ticks), "w /h"
|
||||
);
|
||||
}).collect(Collectors.toList()));
|
||||
@@ -232,13 +242,25 @@ public class HopperCounter
|
||||
*/
|
||||
public static int appropriateColor(int color)
|
||||
{
|
||||
if (color == 0) return MapColor.SNOW.col;
|
||||
if (color == 0)
|
||||
{
|
||||
return MapColor.SNOW.col;
|
||||
}
|
||||
int r = (color >> 16 & 255);
|
||||
int g = (color >> 8 & 255);
|
||||
int b = (color & 255);
|
||||
if (r < 70) r = 70;
|
||||
if (g < 70) g = 70;
|
||||
if (b < 70) b = 70;
|
||||
if (r < 70)
|
||||
{
|
||||
r = 70;
|
||||
}
|
||||
if (g < 70)
|
||||
{
|
||||
g = 70;
|
||||
}
|
||||
if (b < 70)
|
||||
{
|
||||
b = 70;
|
||||
}
|
||||
return (r << 16) + (g << 8) + b;
|
||||
}
|
||||
|
||||
@@ -247,19 +269,19 @@ public class HopperCounter
|
||||
* {@link Block#defaultMapColor()} method as these items have those same colours.
|
||||
*/
|
||||
private static final Map<Item, Block> DEFAULTS = Map.ofEntries(
|
||||
entry(Items.DANDELION, Blocks.YELLOW_WOOL),
|
||||
entry(Items.POPPY, Blocks.RED_WOOL),
|
||||
entry(Items.BLUE_ORCHID, Blocks.LIGHT_BLUE_WOOL),
|
||||
entry(Items.ALLIUM, Blocks.MAGENTA_WOOL),
|
||||
entry(Items.DANDELION, Blocks.WOOL.yellow()),
|
||||
entry(Items.POPPY, Blocks.WOOL.red()),
|
||||
entry(Items.BLUE_ORCHID, Blocks.WOOL.lightBlue()),
|
||||
entry(Items.ALLIUM, Blocks.WOOL.magenta()),
|
||||
entry(Items.AZURE_BLUET, Blocks.SNOW_BLOCK),
|
||||
entry(Items.RED_TULIP, Blocks.RED_WOOL),
|
||||
entry(Items.ORANGE_TULIP, Blocks.ORANGE_WOOL),
|
||||
entry(Items.RED_TULIP, Blocks.WOOL.red()),
|
||||
entry(Items.ORANGE_TULIP, Blocks.WOOL.orange()),
|
||||
entry(Items.WHITE_TULIP, Blocks.SNOW_BLOCK),
|
||||
entry(Items.PINK_TULIP, Blocks.PINK_WOOL),
|
||||
entry(Items.PINK_TULIP, Blocks.WOOL.pink()),
|
||||
entry(Items.OXEYE_DAISY, Blocks.SNOW_BLOCK),
|
||||
entry(Items.CORNFLOWER, Blocks.BLUE_WOOL),
|
||||
entry(Items.WITHER_ROSE, Blocks.BLACK_WOOL),
|
||||
entry(Items.LILY_OF_THE_VALLEY, Blocks.WHITE_WOOL),
|
||||
entry(Items.CORNFLOWER, Blocks.WOOL.blue()),
|
||||
entry(Items.WITHER_ROSE, Blocks.WOOL.black()),
|
||||
entry(Items.LILY_OF_THE_VALLEY, Blocks.WOOL.white()),
|
||||
entry(Items.BROWN_MUSHROOM, Blocks.BROWN_MUSHROOM_BLOCK),
|
||||
entry(Items.RED_MUSHROOM, Blocks.RED_MUSHROOM_BLOCK),
|
||||
entry(Items.STICK, Blocks.OAK_PLANKS),
|
||||
@@ -267,70 +289,70 @@ public class HopperCounter
|
||||
entry(Items.IRON_INGOT, Blocks.IRON_BLOCK),
|
||||
entry(Items.DIAMOND, Blocks.DIAMOND_BLOCK),
|
||||
entry(Items.NETHERITE_INGOT, Blocks.NETHERITE_BLOCK),
|
||||
entry(Items.SUNFLOWER, Blocks.YELLOW_WOOL),
|
||||
entry(Items.LILAC, Blocks.MAGENTA_WOOL),
|
||||
entry(Items.ROSE_BUSH, Blocks.RED_WOOL),
|
||||
entry(Items.PEONY, Blocks.PINK_WOOL),
|
||||
entry(Items.CARROT, Blocks.ORANGE_WOOL),
|
||||
entry(Items.APPLE,Blocks.RED_WOOL),
|
||||
entry(Items.WHEAT,Blocks.HAY_BLOCK),
|
||||
entry(Items.PORKCHOP, Blocks.PINK_WOOL),
|
||||
entry(Items.RABBIT,Blocks.PINK_WOOL),
|
||||
entry(Items.CHICKEN,Blocks.WHITE_TERRACOTTA),
|
||||
entry(Items.BEEF,Blocks.NETHERRACK),
|
||||
entry(Items.ENCHANTED_GOLDEN_APPLE,Blocks.GOLD_BLOCK),
|
||||
entry(Items.COD,Blocks.WHITE_TERRACOTTA),
|
||||
entry(Items.SALMON,Blocks.ACACIA_PLANKS),
|
||||
entry(Items.ROTTEN_FLESH,Blocks.BROWN_WOOL),
|
||||
entry(Items.PUFFERFISH,Blocks.YELLOW_TERRACOTTA),
|
||||
entry(Items.TROPICAL_FISH,Blocks.ORANGE_WOOL),
|
||||
entry(Items.POTATO,Blocks.WHITE_TERRACOTTA),
|
||||
entry(Items.MUTTON, Blocks.RED_WOOL),
|
||||
entry(Items.BEETROOT,Blocks.NETHERRACK),
|
||||
entry(Items.MELON_SLICE,Blocks.MELON),
|
||||
entry(Items.POISONOUS_POTATO,Blocks.SLIME_BLOCK),
|
||||
entry(Items.SPIDER_EYE,Blocks.NETHERRACK),
|
||||
entry(Items.GUNPOWDER,Blocks.GRAY_WOOL),
|
||||
entry(Items.TURTLE_SCUTE,Blocks.LIME_WOOL),
|
||||
entry(Items.ARMADILLO_SCUTE,Blocks.ANCIENT_DEBRIS),
|
||||
entry(Items.FEATHER,Blocks.WHITE_WOOL),
|
||||
entry(Items.FLINT,Blocks.BLACK_WOOL),
|
||||
entry(Items.LEATHER,Blocks.SPRUCE_PLANKS),
|
||||
entry(Items.GLOWSTONE_DUST,Blocks.GLOWSTONE),
|
||||
entry(Items.PAPER,Blocks.WHITE_WOOL),
|
||||
entry(Items.BRICK,Blocks.BRICKS),
|
||||
entry(Items.INK_SAC,Blocks.BLACK_WOOL),
|
||||
entry(Items.SNOWBALL,Blocks.SNOW_BLOCK),
|
||||
entry(Items.WATER_BUCKET,Blocks.WATER),
|
||||
entry(Items.LAVA_BUCKET,Blocks.LAVA),
|
||||
entry(Items.MILK_BUCKET,Blocks.WHITE_WOOL),
|
||||
entry(Items.SUNFLOWER, Blocks.WOOL.yellow()),
|
||||
entry(Items.LILAC, Blocks.WOOL.magenta()),
|
||||
entry(Items.ROSE_BUSH, Blocks.WOOL.red()),
|
||||
entry(Items.PEONY, Blocks.WOOL.pink()),
|
||||
entry(Items.CARROT, Blocks.WOOL.orange()),
|
||||
entry(Items.APPLE, Blocks.WOOL.red()),
|
||||
entry(Items.WHEAT, Blocks.HAY_BLOCK),
|
||||
entry(Items.PORKCHOP, Blocks.WOOL.pink()),
|
||||
entry(Items.RABBIT, Blocks.WOOL.pink()),
|
||||
entry(Items.CHICKEN, Blocks.DYED_TERRACOTTA.white()),
|
||||
entry(Items.BEEF, Blocks.NETHERRACK),
|
||||
entry(Items.ENCHANTED_GOLDEN_APPLE, Blocks.GOLD_BLOCK),
|
||||
entry(Items.COD, Blocks.DYED_TERRACOTTA.white()),
|
||||
entry(Items.SALMON, Blocks.ACACIA_PLANKS),
|
||||
entry(Items.ROTTEN_FLESH, Blocks.WOOL.brown()),
|
||||
entry(Items.PUFFERFISH, Blocks.DYED_TERRACOTTA.orange()),
|
||||
entry(Items.TROPICAL_FISH, Blocks.WOOL.orange()),
|
||||
entry(Items.POTATO, Blocks.DYED_TERRACOTTA.white()),
|
||||
entry(Items.MUTTON, Blocks.WOOL.red()),
|
||||
entry(Items.BEETROOT, Blocks.NETHERRACK),
|
||||
entry(Items.MELON_SLICE, Blocks.MELON),
|
||||
entry(Items.POISONOUS_POTATO, Blocks.SLIME_BLOCK),
|
||||
entry(Items.SPIDER_EYE, Blocks.NETHERRACK),
|
||||
entry(Items.GUNPOWDER, Blocks.WOOL.gray()),
|
||||
entry(Items.TURTLE_SCUTE, Blocks.WOOL.lime()),
|
||||
entry(Items.ARMADILLO_SCUTE, Blocks.ANCIENT_DEBRIS),
|
||||
entry(Items.FEATHER, Blocks.WOOL.white()),
|
||||
entry(Items.FLINT, Blocks.WOOL.black()),
|
||||
entry(Items.LEATHER, Blocks.SPRUCE_PLANKS),
|
||||
entry(Items.GLOWSTONE_DUST, Blocks.GLOWSTONE),
|
||||
entry(Items.PAPER, Blocks.WOOL.white()),
|
||||
entry(Items.BRICK, Blocks.BRICKS),
|
||||
entry(Items.INK_SAC, Blocks.WOOL.black()),
|
||||
entry(Items.SNOWBALL, Blocks.SNOW_BLOCK),
|
||||
entry(Items.WATER_BUCKET, Blocks.WATER),
|
||||
entry(Items.LAVA_BUCKET, Blocks.LAVA),
|
||||
entry(Items.MILK_BUCKET, Blocks.WOOL.white()),
|
||||
entry(Items.CLAY_BALL, Blocks.CLAY),
|
||||
entry(Items.COCOA_BEANS,Blocks.COCOA),
|
||||
entry(Items.BONE,Blocks.BONE_BLOCK),
|
||||
entry(Items.COD_BUCKET,Blocks.BROWN_TERRACOTTA),
|
||||
entry(Items.PUFFERFISH_BUCKET,Blocks.YELLOW_TERRACOTTA),
|
||||
entry(Items.SALMON_BUCKET,Blocks.PINK_TERRACOTTA),
|
||||
entry(Items.TROPICAL_FISH_BUCKET,Blocks.ORANGE_TERRACOTTA),
|
||||
entry(Items.SUGAR,Blocks.WHITE_WOOL),
|
||||
entry(Items.BLAZE_POWDER,Blocks.GOLD_BLOCK),
|
||||
entry(Items.ENDER_PEARL,Blocks.WARPED_PLANKS),
|
||||
entry(Items.NETHER_STAR,Blocks.DIAMOND_BLOCK),
|
||||
entry(Items.PRISMARINE_CRYSTALS,Blocks.SEA_LANTERN),
|
||||
entry(Items.PRISMARINE_SHARD,Blocks.PRISMARINE),
|
||||
entry(Items.RABBIT_HIDE,Blocks.OAK_PLANKS),
|
||||
entry(Items.CHORUS_FRUIT,Blocks.PURPUR_BLOCK),
|
||||
entry(Items.SHULKER_SHELL,Blocks.SHULKER_BOX),
|
||||
entry(Items.NAUTILUS_SHELL,Blocks.BONE_BLOCK),
|
||||
entry(Items.HEART_OF_THE_SEA,Blocks.CONDUIT),
|
||||
entry(Items.HONEYCOMB,Blocks.HONEYCOMB_BLOCK),
|
||||
entry(Items.NAME_TAG,Blocks.BONE_BLOCK),
|
||||
entry(Items.TOTEM_OF_UNDYING,Blocks.YELLOW_TERRACOTTA),
|
||||
entry(Items.TRIDENT,Blocks.PRISMARINE),
|
||||
entry(Items.GHAST_TEAR,Blocks.WHITE_WOOL),
|
||||
entry(Items.PHANTOM_MEMBRANE,Blocks.BONE_BLOCK),
|
||||
entry(Items.EGG,Blocks.BONE_BLOCK),
|
||||
entry(Items.COCOA_BEANS, Blocks.COCOA),
|
||||
entry(Items.BONE, Blocks.BONE_BLOCK),
|
||||
entry(Items.COD_BUCKET, Blocks.DYED_TERRACOTTA.brown()),
|
||||
entry(Items.PUFFERFISH_BUCKET, Blocks.DYED_TERRACOTTA.yellow()),
|
||||
entry(Items.SALMON_BUCKET, Blocks.DYED_TERRACOTTA.pink()),
|
||||
entry(Items.TROPICAL_FISH_BUCKET, Blocks.DYED_TERRACOTTA.orange()),
|
||||
entry(Items.SUGAR, Blocks.WOOL.white()),
|
||||
entry(Items.BLAZE_POWDER, Blocks.GOLD_BLOCK),
|
||||
entry(Items.ENDER_PEARL, Blocks.WARPED_PLANKS),
|
||||
entry(Items.NETHER_STAR, Blocks.DIAMOND_BLOCK),
|
||||
entry(Items.PRISMARINE_CRYSTALS, Blocks.SEA_LANTERN),
|
||||
entry(Items.PRISMARINE_SHARD, Blocks.PRISMARINE),
|
||||
entry(Items.RABBIT_HIDE, Blocks.OAK_PLANKS),
|
||||
entry(Items.CHORUS_FRUIT, Blocks.PURPUR_BLOCK),
|
||||
entry(Items.SHULKER_SHELL, Blocks.SHULKER_BOX),
|
||||
entry(Items.NAUTILUS_SHELL, Blocks.BONE_BLOCK),
|
||||
entry(Items.HEART_OF_THE_SEA, Blocks.CONDUIT),
|
||||
entry(Items.HONEYCOMB, Blocks.HONEYCOMB_BLOCK),
|
||||
entry(Items.NAME_TAG, Blocks.BONE_BLOCK),
|
||||
entry(Items.TOTEM_OF_UNDYING, Blocks.DYED_TERRACOTTA.yellow()),
|
||||
entry(Items.TRIDENT, Blocks.PRISMARINE),
|
||||
entry(Items.GHAST_TEAR, Blocks.WOOL.white()),
|
||||
entry(Items.PHANTOM_MEMBRANE, Blocks.BONE_BLOCK),
|
||||
entry(Items.EGG, Blocks.BONE_BLOCK),
|
||||
//entry(Items.,Blocks.),
|
||||
entry(Items.COPPER_INGOT,Blocks.COPPER_BLOCK),
|
||||
entry(Items.COPPER_INGOT, Blocks.COPPER_BLOCK.weathering().unaffected()),
|
||||
entry(Items.AMETHYST_SHARD, Blocks.AMETHYST_BLOCK));
|
||||
|
||||
/**
|
||||
@@ -338,25 +360,37 @@ public class HopperCounter
|
||||
*/
|
||||
public static TextColor fromItem(Item item, RegistryAccess registryAccess)
|
||||
{
|
||||
if (DEFAULTS.containsKey(item)) return TextColor.fromRgb(appropriateColor(DEFAULTS.get(item).defaultMapColor().col));
|
||||
if (item instanceof DyeItem dye) return TextColor.fromRgb(appropriateColor(dye.getDyeColor().getMapColor().col));
|
||||
if (DEFAULTS.containsKey(item))
|
||||
{
|
||||
return TextColor.fromRgb(appropriateColor(DEFAULTS.get(item).defaultMapColor().col));
|
||||
}
|
||||
if (item instanceof DyeItem dye)
|
||||
{
|
||||
return TextColor.fromRgb(appropriateColor(Optional.ofNullable(dye.getDefaultInstance().get(DataComponents.DYE)).orElse(DyeColor.WHITE).getMapColor().col));
|
||||
}
|
||||
Block block = null;
|
||||
final Registry<Item> itemRegistry = registryAccess.registryOrThrow(Registries.ITEM);
|
||||
final Registry<Block> blockRegistry = registryAccess.registryOrThrow(Registries.BLOCK);
|
||||
ResourceLocation id = itemRegistry.getKey(item);
|
||||
final Registry<Item> itemRegistry = registryAccess.lookupOrThrow(Registries.ITEM);
|
||||
final Registry<Block> blockRegistry = registryAccess.lookupOrThrow(Registries.BLOCK);
|
||||
Identifier id = itemRegistry.getKey(item);
|
||||
if (item instanceof BlockItem blockItem)
|
||||
{
|
||||
block = blockItem.getBlock();
|
||||
}
|
||||
else if (blockRegistry.getOptional(id).isPresent())
|
||||
{
|
||||
block = blockRegistry.get(id);
|
||||
block = blockRegistry.getValue(id);
|
||||
}
|
||||
if (block != null)
|
||||
{
|
||||
if (block instanceof AbstractBannerBlock) return TextColor.fromRgb(appropriateColor(((AbstractBannerBlock) block).getColor().getMapColor().col));
|
||||
if (block instanceof BeaconBeamBlock) return TextColor.fromRgb(appropriateColor( ((BeaconBeamBlock) block).getColor().getMapColor().col));
|
||||
return TextColor.fromRgb(appropriateColor( block.defaultMapColor().col));
|
||||
if (block instanceof AbstractBannerBlock)
|
||||
{
|
||||
return TextColor.fromRgb(appropriateColor(((AbstractBannerBlock) block).getColor().getMapColor().col));
|
||||
}
|
||||
if (block instanceof BeaconBeamBlock)
|
||||
{
|
||||
return TextColor.fromRgb(appropriateColor(((BeaconBeamBlock) block).getColor().getMapColor().col));
|
||||
}
|
||||
return TextColor.fromRgb(appropriateColor(block.defaultMapColor().col));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -365,38 +399,45 @@ public class HopperCounter
|
||||
* Guesses the item's colour from the item itself. It first calls {@link HopperCounter#fromItem} to see if it has a
|
||||
* valid colour there, if not just makes a guess, and if that fails just returns null
|
||||
*/
|
||||
public static TextColor guessColor(Item item, RegistryAccess registryAccess)
|
||||
public static TextColor guessColor(Item item, Level level)
|
||||
{
|
||||
RegistryAccess registryAccess = level.registryAccess();
|
||||
TextColor direct = fromItem(item, registryAccess);
|
||||
if (direct != null) return direct;
|
||||
if (CarpetServer.minecraft_server == null) return WHITE;
|
||||
|
||||
ResourceLocation id = registryAccess.registryOrThrow(Registries.ITEM).getKey(item);
|
||||
for (RecipeType<?> type: registryAccess.registryOrThrow(Registries.RECIPE_TYPE))
|
||||
if (direct != null)
|
||||
{
|
||||
for (Recipe<?> r: ((RecipeManagerInterface) CarpetServer.minecraft_server.getRecipeManager()).getAllMatching(type, id, registryAccess))
|
||||
return direct;
|
||||
}
|
||||
if (CarpetServer.minecraft_server == null)
|
||||
{
|
||||
return WHITE;
|
||||
}
|
||||
|
||||
Identifier id = registryAccess.lookupOrThrow(Registries.ITEM).getKey(item);
|
||||
if (id == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Recipe<?> r : RecipeHelper.getRecipesForOutput(CarpetServer.minecraft_server.getRecipeManager(), id, level))
|
||||
{
|
||||
for (Ingredient ingredient : r.placementInfo().ingredients())
|
||||
{
|
||||
for (Ingredient ingredient: r.getIngredients())
|
||||
Optional<Holder<Item>> match = ingredient.items().filter(stack -> fromItem(stack.value(), registryAccess) != null).findFirst();
|
||||
if (match.isPresent())
|
||||
{
|
||||
for (Collection<ItemStack> stacks : ((IngredientInterface) (Object) ingredient).getRecipeStacks())
|
||||
{
|
||||
for (ItemStack iStak : stacks)
|
||||
{
|
||||
TextColor cand = fromItem(iStak.getItem(), registryAccess);
|
||||
if (cand != null)
|
||||
return cand;
|
||||
}
|
||||
}
|
||||
return fromItem(match.get().value(), registryAccess);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hopper counter for the given color
|
||||
*/
|
||||
public static HopperCounter getCounter(DyeColor color) {
|
||||
public static HopperCounter getCounter(DyeColor color)
|
||||
{
|
||||
return COUNTERS.get(color);
|
||||
}
|
||||
|
||||
@@ -421,6 +462,6 @@ public class HopperCounter
|
||||
*/
|
||||
public long getTotalItems()
|
||||
{
|
||||
return counter.isEmpty()?0:counter.values().longStream().sum();
|
||||
return counter.isEmpty() ? 0 : counter.values().longStream().sum();
|
||||
}
|
||||
}
|
||||
@@ -1,80 +1,39 @@
|
||||
package carpet.helpers;
|
||||
//Author: masa
|
||||
|
||||
import java.math.RoundingMode;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.Util;
|
||||
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.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.entity.item.PrimedTnt;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
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.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.storage.loot.LootParams;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import carpet.logging.logHelpers.ExplosionLogHelper;
|
||||
import carpet.mixins.ExplosionAccessor;
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.utils.Messenger;
|
||||
import it.unimi.dsi.fastutil.objects.Object2DoubleOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import static carpet.script.CarpetEventServer.Event.EXPLOSION_OUTCOME;
|
||||
|
||||
public class OptimizedExplosion
|
||||
{
|
||||
private static List<Entity> entitylist;
|
||||
private static Vec3 vec3dmem;
|
||||
private static long tickmem;
|
||||
// For disabling the explosion particles and sound
|
||||
public static int explosionSound = 0;
|
||||
|
||||
// masa's optimizations
|
||||
private static Object2DoubleOpenHashMap<Pair<Vec3, AABB>> densityCache = new Object2DoubleOpenHashMap<>();
|
||||
private static MutablePair<Vec3, AABB> pairMutable = new MutablePair<>();
|
||||
private static Object2ObjectOpenHashMap<BlockPos, BlockState> stateCache = new Object2ObjectOpenHashMap<>();
|
||||
private static Object2ObjectOpenHashMap<BlockPos, FluidState> fluidCache = new Object2ObjectOpenHashMap<>();
|
||||
private static BlockPos.MutableBlockPos posMutable = new BlockPos.MutableBlockPos(0, 0, 0);
|
||||
private static ObjectOpenHashSet<BlockPos> affectedBlockPositionsSet = new ObjectOpenHashSet<>();
|
||||
private static boolean firstRay;
|
||||
private static boolean rayCalcDone;
|
||||
private static ArrayList<Float> chances = new ArrayList<>();
|
||||
private static BlockPos blastChanceLocation;
|
||||
|
||||
// Creating entity list for scarpet event
|
||||
private static List<Entity> entityList = new ArrayList<>();
|
||||
|
||||
public static void doExplosionA(Explosion e, ExplosionLogHelper eLogger) {
|
||||
public static List<BlockPos> doExplosionA(Explosion e, ExplosionLogHelper eLogger) {
|
||||
ExplosionAccessor eAccess = (ExplosionAccessor) e;
|
||||
|
||||
entityList.clear();
|
||||
boolean eventNeeded = EXPLOSION_OUTCOME.isNeeded() && !eAccess.getLevel().isClientSide();
|
||||
blastCalc(e);
|
||||
|
||||
List<BlockPos> toBlow;
|
||||
|
||||
if (!CarpetSettings.explosionNoBlockDamage && eAccess.getDamageSource() != null) {
|
||||
rayCalcDone = false;
|
||||
@@ -88,291 +47,14 @@ public class OptimizedExplosion
|
||||
stateCache.clear();
|
||||
fluidCache.clear();
|
||||
|
||||
e.getToBlow().addAll(affectedBlockPositionsSet);
|
||||
toBlow = new ArrayList<>(affectedBlockPositionsSet);
|
||||
affectedBlockPositionsSet.clear();
|
||||
} else {
|
||||
toBlow = Collections.emptyList();
|
||||
}
|
||||
|
||||
float f3 = eAccess.getRadius() * 2.0F;
|
||||
int k1 = Mth.floor(eAccess.getX() - (double) f3 - 1.0D);
|
||||
int l1 = Mth.floor(eAccess.getX() + (double) f3 + 1.0D);
|
||||
int i2 = Mth.floor(eAccess.getY() - (double) f3 - 1.0D);
|
||||
int i1 = Mth.floor(eAccess.getY() + (double) f3 + 1.0D);
|
||||
int j2 = Mth.floor(eAccess.getZ() - (double) f3 - 1.0D);
|
||||
int j1 = Mth.floor(eAccess.getZ() + (double) f3 + 1.0D);
|
||||
Vec3 vec3d = new Vec3(eAccess.getX(), eAccess.getY(), eAccess.getZ());
|
||||
|
||||
if (vec3dmem == null || !vec3dmem.equals(vec3d) || tickmem != eAccess.getLevel().getGameTime()) {
|
||||
vec3dmem = vec3d;
|
||||
tickmem = eAccess.getLevel().getGameTime();
|
||||
entitylist = eAccess.getLevel().getEntities(null, new AABB(k1, i2, j2, l1, i1, j1));
|
||||
explosionSound = 0;
|
||||
}
|
||||
|
||||
explosionSound++;
|
||||
|
||||
Entity explodingEntity = eAccess.getSource();
|
||||
for (int k2 = 0; k2 < entitylist.size(); ++k2) {
|
||||
Entity entity = entitylist.get(k2);
|
||||
|
||||
|
||||
if (entity == explodingEntity) {
|
||||
// entitylist.remove(k2);
|
||||
removeFast(entitylist, k2);
|
||||
k2--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entity instanceof PrimedTnt && explodingEntity != null &&
|
||||
entity.getX() == explodingEntity.getX() &&
|
||||
entity.getY() == explodingEntity.getY() &&
|
||||
entity.getZ() == explodingEntity.getZ()) {
|
||||
if (eLogger != null) {
|
||||
eLogger.onEntityImpacted(entity, new Vec3(0,-0.9923437498509884d, 0));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!entity.ignoreExplosion(e)) {
|
||||
double d12 = Math.sqrt(entity.distanceToSqr(eAccess.getX(), eAccess.getY(), eAccess.getZ())) / (double) f3;
|
||||
|
||||
if (d12 <= 1.0D) {
|
||||
double d5 = entity.getX() - eAccess.getX();
|
||||
// Change in 1.16 snapshots to fix a bug with TNT jumping
|
||||
double d7 = (entity instanceof PrimedTnt ? entity.getY() : entity.getEyeY()) - eAccess.getY();
|
||||
double d9 = entity.getZ() - eAccess.getZ();
|
||||
double d13 = (double) Math.sqrt(d5 * d5 + d7 * d7 + d9 * d9);
|
||||
|
||||
if (d13 != 0.0D) {
|
||||
d5 = d5 / d13;
|
||||
d7 = d7 / d13;
|
||||
d9 = d9 / d13;
|
||||
double density;
|
||||
|
||||
pairMutable.setLeft(vec3d);
|
||||
pairMutable.setRight(entity.getBoundingBox());
|
||||
density = densityCache.getOrDefault(pairMutable, Double.MAX_VALUE);
|
||||
|
||||
if (density == Double.MAX_VALUE)
|
||||
{
|
||||
Pair<Vec3, AABB> pair = Pair.of(vec3d, entity.getBoundingBox());
|
||||
density = Explosion.getSeenPercent(vec3d, entity);
|
||||
densityCache.put(pair, density);
|
||||
}
|
||||
|
||||
// If it is needed, it saves the entity
|
||||
if (eventNeeded) {
|
||||
entityList.add(entity);
|
||||
}
|
||||
|
||||
double d10 = (1.0D - d12) * density;
|
||||
if (eAccess.getDamageSource() != null)
|
||||
{
|
||||
entity.hurt(eAccess.getDamageSource(),
|
||||
(float) ((int) ((d10 * d10 + d10) / 2.0D * 7.0D * (double) f3 + 1.0D)));
|
||||
}
|
||||
double d11 = d10;
|
||||
|
||||
if (entity instanceof LivingEntity lev) {
|
||||
d11 = d10 * Mth.clamp(1.0 - lev.getAttributeValue(Attributes.EXPLOSION_KNOCKBACK_RESISTANCE), 0.0, 1.0);
|
||||
}
|
||||
|
||||
if (eLogger != null) {
|
||||
eLogger.onEntityImpacted(entity, new Vec3(d5 * d11, d7 * d11, d9 * d11));
|
||||
}
|
||||
|
||||
entity.setDeltaMovement(entity.getDeltaMovement().add(d5 * d11, d7 * d11, d9 * d11));
|
||||
|
||||
if (entity instanceof Player player) {
|
||||
|
||||
if (!player.isSpectator()
|
||||
&& (!player.isCreative() || !player.getAbilities().flying)) { //getAbilities
|
||||
e.getHitPlayers().put(player, new Vec3(d5 * d10, d7 * d10, d9 * d10));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
densityCache.clear();
|
||||
}
|
||||
|
||||
public static void doExplosionB(Explosion e, boolean spawnParticles)
|
||||
{
|
||||
ExplosionAccessor eAccess = (ExplosionAccessor) e;
|
||||
Level world = eAccess.getLevel();
|
||||
double posX = eAccess.getX();
|
||||
double posY = eAccess.getY();
|
||||
double posZ = eAccess.getZ();
|
||||
|
||||
// If it is needed, calls scarpet event
|
||||
if (EXPLOSION_OUTCOME.isNeeded() && !world.isClientSide()) {
|
||||
EXPLOSION_OUTCOME.onExplosion((ServerLevel) world, eAccess.getSource(), e::getIndirectSourceEntity, eAccess.getX(), eAccess.getY(), eAccess.getZ(), eAccess.getRadius(), eAccess.isFire(), e.getToBlow(), entityList, eAccess.getBlockInteraction());
|
||||
}
|
||||
|
||||
boolean damagesTerrain = eAccess.getBlockInteraction() != Explosion.BlockInteraction.KEEP;
|
||||
|
||||
// explosionSound incremented till disabling the explosion particles and sound
|
||||
if (explosionSound < 100 || explosionSound % 100 == 0)
|
||||
{
|
||||
world.playSound(null, posX, posY, posZ, SoundEvents.GENERIC_EXPLODE.value(), SoundSource.BLOCKS, 4.0F,
|
||||
(1.0F + (world.random.nextFloat() - world.random.nextFloat()) * 0.2F) * 0.7F);
|
||||
|
||||
if (spawnParticles)
|
||||
{
|
||||
if (eAccess.getRadius() >= 2.0F && damagesTerrain)
|
||||
{
|
||||
world.addParticle(ParticleTypes.EXPLOSION_EMITTER, posX, posY, posZ, 1.0D, 0.0D, 0.0D);
|
||||
}
|
||||
else
|
||||
{
|
||||
world.addParticle(ParticleTypes.EXPLOSION, posX, posY, posZ, 1.0D, 0.0D, 0.0D);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (damagesTerrain)
|
||||
{
|
||||
ObjectArrayList<Pair<ItemStack, BlockPos>> objectArrayList = new ObjectArrayList<>();
|
||||
Util.shuffle((ObjectArrayList<BlockPos>) e.getToBlow(), world.random);
|
||||
|
||||
boolean dropFromExplosions = CarpetSettings.xpFromExplosions || e.getIndirectSourceEntity() instanceof Player;
|
||||
|
||||
for (BlockPos blockpos : e.getToBlow())
|
||||
{
|
||||
BlockState state = world.getBlockState(blockpos);
|
||||
Block block = state.getBlock();
|
||||
|
||||
if (!state.isAir())
|
||||
{
|
||||
if (block.dropFromExplosion(e) && world instanceof ServerLevel serverLevel)
|
||||
{
|
||||
BlockEntity blockEntity = state.hasBlockEntity() ? world.getBlockEntity(blockpos) : null; //hasBlockEntity()
|
||||
|
||||
LootParams.Builder lootBuilder = (new LootParams.Builder((ServerLevel)eAccess.getLevel()))
|
||||
.withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockpos))
|
||||
.withParameter(LootContextParams.TOOL, ItemStack.EMPTY)
|
||||
.withOptionalParameter(LootContextParams.BLOCK_ENTITY, blockEntity)
|
||||
.withOptionalParameter(LootContextParams.THIS_ENTITY, eAccess.getSource());
|
||||
|
||||
if (eAccess.getBlockInteraction() == Explosion.BlockInteraction.DESTROY_WITH_DECAY)
|
||||
lootBuilder.withParameter(LootContextParams.EXPLOSION_RADIUS, eAccess.getRadius());
|
||||
|
||||
state.spawnAfterBreak(serverLevel, blockpos, ItemStack.EMPTY, dropFromExplosions);
|
||||
|
||||
state.getDrops(lootBuilder).forEach((itemStackx) -> {
|
||||
method_24023(objectArrayList, itemStackx, blockpos.immutable());
|
||||
});
|
||||
}
|
||||
|
||||
world.setBlock(blockpos, Blocks.AIR.defaultBlockState(), 3);
|
||||
block.wasExploded(world, blockpos, e);
|
||||
}
|
||||
}
|
||||
objectArrayList.forEach(p -> Block.popResource(world, p.getRight(), p.getLeft()));
|
||||
|
||||
}
|
||||
|
||||
if (eAccess.isFire())
|
||||
{
|
||||
for (BlockPos blockpos1 : e.getToBlow())
|
||||
{
|
||||
// Use the same Chunk reference because the positions are in the same xz-column
|
||||
ChunkAccess chunk = world.getChunk(blockpos1.getX() >> 4, blockpos1.getZ() >> 4);
|
||||
|
||||
BlockPos down = blockpos1.below(1);
|
||||
if (eAccess.getRandom().nextInt(3) == 0 &&
|
||||
chunk.getBlockState(blockpos1).isAir() &&
|
||||
chunk.getBlockState(down).isSolidRender(world, down)
|
||||
)
|
||||
{
|
||||
world.setBlockAndUpdate(blockpos1, Blocks.FIRE.defaultBlockState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copied from Explosion, need to move the code to the explosion code anyways and use shadows for
|
||||
// simplicity, its not jarmodding anyways
|
||||
private static void method_24023(ObjectArrayList<Pair<ItemStack, BlockPos>> objectArrayList, ItemStack itemStack, BlockPos blockPos) {
|
||||
int i = objectArrayList.size();
|
||||
|
||||
for(int j = 0; j < i; ++j) {
|
||||
Pair<ItemStack, BlockPos> pair = objectArrayList.get(j);
|
||||
ItemStack itemStack2 = pair.getLeft();
|
||||
if (ItemEntity.areMergable(itemStack2, itemStack)) {
|
||||
ItemStack itemStack3 = ItemEntity.merge(itemStack2, itemStack, 16);
|
||||
objectArrayList.set(j, Pair.of(itemStack3, pair.getRight()));
|
||||
if (itemStack.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
objectArrayList.add(Pair.of(itemStack, blockPos));
|
||||
}
|
||||
|
||||
private static void removeFast(List<Entity> lst, int index) {
|
||||
if (index < lst.size() - 1)
|
||||
lst.set(index, lst.get(lst.size() - 1));
|
||||
lst.remove(lst.size() - 1);
|
||||
}
|
||||
|
||||
private static void rayCalcs(Explosion e) {
|
||||
ExplosionAccessor eAccess = (ExplosionAccessor) e;
|
||||
boolean first = true;
|
||||
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
for (int k = 0; k < 16; ++k) {
|
||||
for (int l = 0; l < 16; ++l) {
|
||||
if (j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15) {
|
||||
double d0 = (double) ((float) j / 15.0F * 2.0F - 1.0F);
|
||||
double d1 = (double) ((float) k / 15.0F * 2.0F - 1.0F);
|
||||
double d2 = (double) ((float) l / 15.0F * 2.0F - 1.0F);
|
||||
double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
|
||||
d0 = d0 / d3;
|
||||
d1 = d1 / d3;
|
||||
d2 = d2 / d3;
|
||||
float rand = eAccess.getLevel().random.nextFloat();
|
||||
if (CarpetSettings.tntRandomRange >= 0) {
|
||||
rand = (float) CarpetSettings.tntRandomRange;
|
||||
}
|
||||
float f = eAccess.getRadius() * (0.7F + rand * 0.6F);
|
||||
double d4 = eAccess.getX();
|
||||
double d6 = eAccess.getY();
|
||||
double d8 = eAccess.getZ();
|
||||
|
||||
for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
|
||||
BlockPos blockpos = BlockPos.containing(d4, d6, d8);
|
||||
BlockState state = eAccess.getLevel().getBlockState(blockpos);
|
||||
FluidState fluidState = eAccess.getLevel().getFluidState(blockpos);
|
||||
|
||||
if (!state.isAir()) {
|
||||
float f2 = Math.max(state.getBlock().getExplosionResistance(), fluidState.getExplosionResistance());
|
||||
if (eAccess.getSource() != null)
|
||||
f2 = eAccess.getSource().getBlockExplosionResistance(e, eAccess.getLevel(), blockpos, state, fluidState, f2);
|
||||
f -= (f2 + 0.3F) * 0.3F;
|
||||
}
|
||||
|
||||
if (f > 0.0F && (eAccess.getSource() == null ||
|
||||
eAccess.getSource().shouldBlockExplode(e, eAccess.getLevel(), blockpos, state, f)))
|
||||
{
|
||||
affectedBlockPositionsSet.add(blockpos);
|
||||
}
|
||||
else if (first) {
|
||||
return;
|
||||
}
|
||||
|
||||
first = false;
|
||||
|
||||
d4 += d0 * 0.30000001192092896D;
|
||||
d6 += d1 * 0.30000001192092896D;
|
||||
d8 += d2 * 0.30000001192092896D;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return toBlow;
|
||||
}
|
||||
|
||||
private static void getAffectedPositionsOnPlaneX(Explosion e, int x, int yStart, int yEnd, int zStart, int zEnd)
|
||||
@@ -451,12 +133,13 @@ public class OptimizedExplosion
|
||||
double xInc = (xRel / len) * 0.3;
|
||||
double yInc = (yRel / len) * 0.3;
|
||||
double zInc = (zRel / len) * 0.3;
|
||||
float rand = eAccess.getLevel().random.nextFloat();
|
||||
float rand = eAccess.getLevel().getRandom().nextFloat();
|
||||
float sizeRand = (CarpetSettings.tntRandomRange >= 0 ? (float) CarpetSettings.tntRandomRange : rand);
|
||||
float size = eAccess.getRadius() * (0.7F + sizeRand * 0.6F);
|
||||
double posX = eAccess.getX();
|
||||
double posY = eAccess.getY();
|
||||
double posZ = eAccess.getZ();
|
||||
Vec3 vec3 = eAccess.getCenter();
|
||||
double posX = vec3.x;
|
||||
double posY = vec3.y;
|
||||
double posZ = vec3.z;
|
||||
|
||||
for (float f1 = 0.3F; size > 0.0F; size -= 0.22500001F)
|
||||
{
|
||||
@@ -508,112 +191,4 @@ public class OptimizedExplosion
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void setBlastChanceLocation(BlockPos p){
|
||||
blastChanceLocation = p;
|
||||
}
|
||||
|
||||
private static void blastCalc(Explosion e){
|
||||
ExplosionAccessor eAccess = (ExplosionAccessor) e;
|
||||
if(blastChanceLocation == null || blastChanceLocation.distToLowCornerSqr(eAccess.getX(), eAccess.getY(), eAccess.getZ()) > 200) return;
|
||||
chances.clear();
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
for (int k = 0; k < 16; ++k) {
|
||||
for (int l = 0; l < 16; ++l) {
|
||||
if (j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15) {
|
||||
double d0 = (double) ((float) j / 15.0F * 2.0F - 1.0F);
|
||||
double d1 = (double) ((float) k / 15.0F * 2.0F - 1.0F);
|
||||
double d2 = (double) ((float) l / 15.0F * 2.0F - 1.0F);
|
||||
double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
|
||||
d0 = d0 / d3;
|
||||
d1 = d1 / d3;
|
||||
d2 = d2 / d3;
|
||||
float f = eAccess.getRadius() * (0.7F + 0.6F);
|
||||
double d4 = eAccess.getX();
|
||||
double d6 = eAccess.getY();
|
||||
double d8 = eAccess.getZ();
|
||||
boolean found = false;
|
||||
|
||||
for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
|
||||
BlockPos blockpos = BlockPos.containing(d4, d6, d8);
|
||||
BlockState state = eAccess.getLevel().getBlockState(blockpos);
|
||||
FluidState fluidState = eAccess.getLevel().getFluidState(blockpos);
|
||||
|
||||
if (!state.isAir()) {
|
||||
float f2 = Math.max(state.getBlock().getExplosionResistance(), fluidState.getExplosionResistance());
|
||||
if (eAccess.getSource() != null)
|
||||
f2 = eAccess.getSource().getBlockExplosionResistance(e, eAccess.getLevel(), blockpos, state, fluidState, f2);
|
||||
f -= (f2 + 0.3F) * 0.3F;
|
||||
}
|
||||
|
||||
if (f > 0.0F && (eAccess.getSource() == null ||
|
||||
eAccess.getSource().shouldBlockExplode(e, eAccess.getLevel(), blockpos, state, f))) {
|
||||
if(!found && blockpos.equals(blastChanceLocation)){
|
||||
chances.add(f);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
d4 += d0 * 0.30000001192092896D;
|
||||
d6 += d1 * 0.30000001192092896D;
|
||||
d8 += d2 * 0.30000001192092896D;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//showTNTblastChance(e);
|
||||
}
|
||||
|
||||
private static void showTNTblastChance(Explosion e){
|
||||
ExplosionAccessor eAccess = (ExplosionAccessor) e;
|
||||
double randMax = 0.6F * eAccess.getRadius();
|
||||
double total = 0;
|
||||
boolean fullyBlownUp = false;
|
||||
boolean first = true;
|
||||
int rays = 0;
|
||||
for(float f3 : chances){
|
||||
rays++;
|
||||
double calc = f3 - randMax;
|
||||
if(calc > 0) fullyBlownUp = true;
|
||||
double chancePerRay = (Math.abs(calc) / randMax);
|
||||
if(!fullyBlownUp){
|
||||
if(first){
|
||||
first = false;
|
||||
total = chancePerRay;
|
||||
}else {
|
||||
total = total * chancePerRay;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(fullyBlownUp) total = 0;
|
||||
double chance = 1 - total;
|
||||
NumberFormat nf = NumberFormat.getNumberInstance();
|
||||
nf.setRoundingMode (RoundingMode.DOWN);
|
||||
nf.setMaximumFractionDigits(2);
|
||||
for(Player player : eAccess.getLevel().players()){
|
||||
Messenger.m(player,"w Pop: ",
|
||||
"c " + nf.format(chance) + " ",
|
||||
"^w Chance for the block to be destroyed by the blast: " + chance,
|
||||
"?" + chance,
|
||||
"w Remain: ",
|
||||
String.format("c %.2f ", total),
|
||||
"^w Chance the block survives the blast: " + total,
|
||||
"?" + total,
|
||||
"w Rays: ",
|
||||
String.format("c %d ", rays),
|
||||
"^w TNT blast rays going through the block",
|
||||
"?" + rays,
|
||||
"w Size: ",
|
||||
String.format("c %.1f ", eAccess.getRadius()),
|
||||
"^w TNT blast size",
|
||||
"?" + eAccess.getRadius(),
|
||||
"w @: ",
|
||||
String.format("c [%.1f %.1f %.1f] ", eAccess.getX(), eAccess.getY(), eAccess.getZ()),
|
||||
"^w TNT blast location X:" + eAccess.getX() + " Y:" + eAccess.getY() + " Z:" + eAccess.getZ(),
|
||||
"?" + eAccess.getX() + " " + eAccess.getY() + " " + eAccess.getZ()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,18 @@
|
||||
package carpet.helpers;
|
||||
|
||||
import carpet.script.utils.ParticleParser;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.core.particles.ParticleType;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class ParticleDisplay
|
||||
{
|
||||
public static void drawParticleLine(ServerPlayer player, Vec3 from, Vec3 to, String main, String accent, int count, double spread)
|
||||
public static void drawParticleLine(ServerPlayer player, Vec3 from, Vec3 to, ParticleOptions mainParticle, ParticleOptions accentParticle, int count, double spread)
|
||||
{
|
||||
ParticleOptions accentParticle = ParticleParser.getEffect(accent, player.server.registryAccess());
|
||||
ParticleOptions mainParticle = ParticleParser.getEffect(main, player.server.registryAccess());
|
||||
|
||||
if (accentParticle != null) player.serverLevel().sendParticles(
|
||||
if (accentParticle != null) player.level().sendParticles(
|
||||
player,
|
||||
accentParticle,
|
||||
true,
|
||||
true, true,
|
||||
to.x, to.y, to.z, count,
|
||||
spread, spread, spread, 0.0);
|
||||
|
||||
@@ -28,12 +22,12 @@ public class ParticleDisplay
|
||||
Vec3 incvec = to.subtract(from).normalize();// multiply(50/sqrt(lineLengthSq));
|
||||
for (Vec3 delta = new Vec3(0.0,0.0,0.0);
|
||||
delta.lengthSqr() < lineLengthSq;
|
||||
delta = delta.add(incvec.scale(player.level().random.nextFloat())))
|
||||
delta = delta.add(incvec.scale(player.level().getRandom().nextFloat())))
|
||||
{
|
||||
player.serverLevel().sendParticles(
|
||||
player.level().sendParticles(
|
||||
player,
|
||||
mainParticle,
|
||||
true,
|
||||
true, true,
|
||||
delta.x+from.x, delta.y+from.y, delta.z+from.z, 1,
|
||||
0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
@@ -676,7 +676,7 @@ public class RedstoneWireTurbo
|
||||
// call BlockStateBase#neighborChanged directly. This change mostly
|
||||
// restores old behavior, at the cost of bypassing the
|
||||
// max-chained-neighbor-updates server property.
|
||||
worldIn.getBlockState(upd.self).handleNeighborChanged(worldIn, upd.self, wire, upd.parent, false);
|
||||
worldIn.getBlockState(upd.self).handleNeighborChanged(worldIn, upd.self, wire, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -951,7 +951,7 @@ public class RedstoneWireTurbo
|
||||
BlockPos neighborPos = pos.relative(dir);
|
||||
BlockState neighborState = level.getBlockState(neighborPos);
|
||||
|
||||
BlockState newState = neighborState.updateShape(dir.getOpposite(), state, level, neighborPos, pos);
|
||||
BlockState newState = neighborState.updateShape(level, level, neighborPos, dir.getOpposite(), pos, state, level.getRandom());
|
||||
Block.updateOrDestroy(neighborState, newState, level, neighborPos, Block.UPDATE_CLIENTS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
|
||||
@@ -80,7 +80,7 @@ public class ExplosionLogHelper
|
||||
messages.add(c((k.pos.equals(pos))?"r - TNT":"w - ",
|
||||
Messenger.dblt((k.pos.equals(pos))?"r":"y", k.pos.x, k.pos.y, k.pos.z), "w dV",
|
||||
Messenger.dblt("d", k.accel.x, k.accel.y, k.accel.z),
|
||||
"w "+ regs.registryOrThrow(Registries.ENTITY_TYPE).getKey(k.type).getPath(), (v>1)?"l ("+v+")":""
|
||||
"w "+ regs.lookupOrThrow(Registries.ENTITY_TYPE).getKey(k.type).getPath(), (v>1)?"l ("+v+")":""
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@ package carpet.logging.logHelpers;
|
||||
|
||||
import carpet.helpers.ParticleDisplay;
|
||||
import carpet.logging.LoggerRegistry;
|
||||
import net.minecraft.core.particles.DustParticleOptions;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
@@ -31,8 +34,8 @@ public class PathfindingVisualizer
|
||||
if (minDuration < 1)
|
||||
minDuration = 1;
|
||||
|
||||
String accent = successful ? "happy_villager" : "angry_villager";
|
||||
String color = (miliseconds/minDuration < 2)? "dust 1 1 0 1" : ((miliseconds/minDuration < 4)?"dust 1 0.5 0 1":"dust 1 0 0 1");
|
||||
ParticleOptions accent = successful ? ParticleTypes.HAPPY_VILLAGER : ParticleTypes.ANGRY_VILLAGER;
|
||||
ParticleOptions color = (miliseconds/minDuration < 2)? new DustParticleOptions(0xffffff00, 1) : ((miliseconds/minDuration < 4)?new DustParticleOptions(0xFFFF7700, 1): new DustParticleOptions(0xFFFF0000, 1));
|
||||
ParticleDisplay.drawParticleLine((ServerPlayer) player, entity.position(), target, color, accent, 5, 0.5);
|
||||
return null;
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@ import carpet.logging.LoggerRegistry;
|
||||
import carpet.logging.logHelpers.TrajectoryLogHelper;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.projectile.AbstractArrow;
|
||||
import net.minecraft.world.entity.projectile.arrow.AbstractArrow;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
@@ -23,7 +23,7 @@ public abstract class AbstractArrowMixin extends Entity
|
||||
@Inject(method = "<init>(Lnet/minecraft/world/entity/EntityType;DDDLnet/minecraft/world/level/Level;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemStack;)V", at = @At("RETURN"))
|
||||
private void addLogger(final EntityType entityType, final double x, final double y, final double z, final Level level, final ItemStack itemStack, final ItemStack weapon, final CallbackInfo ci)
|
||||
{
|
||||
if (LoggerRegistry.__projectiles && !level.isClientSide)
|
||||
if (LoggerRegistry.__projectiles && !level.isClientSide())
|
||||
logHelper = new TrajectoryLogHelper("projectiles");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.cauldron.CauldronInteraction;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.ItemInteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.AbstractCauldronBlock;
|
||||
import net.minecraft.world.level.block.ShulkerBoxBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(AbstractCauldronBlock.class)
|
||||
public class AbstractCauldronBlock_stackableSBoxesMixin
|
||||
{
|
||||
@Redirect(method = "useItemOn", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/core/cauldron/CauldronInteraction;interact(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/ItemInteractionResult;"
|
||||
))
|
||||
private ItemInteractionResult wrapInteractor(final CauldronInteraction cauldronBehavior, final BlockState blockState, final Level world, final BlockPos blockPos, final Player playerEntity, final InteractionHand hand, final ItemStack itemStack)
|
||||
{
|
||||
int count = -1;
|
||||
if (CarpetSettings.shulkerBoxStackSize > 1 && itemStack.getItem() instanceof BlockItem && ((BlockItem)itemStack.getItem()).getBlock() instanceof ShulkerBoxBlock)
|
||||
count = itemStack.getCount();
|
||||
ItemInteractionResult result = cauldronBehavior.interact(blockState, world, blockPos, playerEntity, hand, itemStack);
|
||||
if (count > 0 && result.consumesAction())
|
||||
{
|
||||
ItemStack current = playerEntity.getItemInHand(hand);
|
||||
if (current.getItem() instanceof BlockItem && ((BlockItem)itemStack.getItem()).getBlock() instanceof ShulkerBoxBlock)
|
||||
current.setCount(count);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
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;
|
||||
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.ClickType;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
@Mixin(AbstractContainerMenu.class)
|
||||
public abstract class AbstractContainerMenu_ctrlQCraftingMixin
|
||||
{
|
||||
|
||||
@Shadow public abstract void clicked(int int_1, int int_2, ClickType slotActionType_1, Player playerEntity_1);
|
||||
|
||||
@Shadow public abstract void broadcastChanges();
|
||||
|
||||
@Shadow @Final public NonNullList<Slot> slots;
|
||||
|
||||
@Shadow protected abstract void resetQuickCraft();
|
||||
|
||||
@Shadow public abstract ItemStack getCarried();
|
||||
|
||||
@Inject( method = "doClick", at = @At(value = "HEAD"), cancellable = true)
|
||||
private void onThrowClick(int slotId, int clickData, ClickType actionType, Player playerEntity, CallbackInfo ci)
|
||||
{
|
||||
if (actionType == ClickType.THROW && CarpetSettings.ctrlQCraftingFix && this.getCarried().isEmpty() && slotId >= 0)
|
||||
{
|
||||
Slot slot_4 = slots.get(slotId);
|
||||
if (/*slot_4 != null && */slot_4.hasItem() && slot_4.mayPickup(playerEntity))
|
||||
{
|
||||
if(slotId == 0 && clickData == 1)
|
||||
{
|
||||
Item craftedItem = slot_4.getItem().getItem();
|
||||
while(slot_4.hasItem() && slot_4.getItem().getItem() == craftedItem)
|
||||
{
|
||||
this.clicked(slotId, 0, ClickType.THROW, playerEntity);
|
||||
}
|
||||
this.broadcastChanges();
|
||||
this.resetQuickCraft();
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ import java.util.List;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.ClickType;
|
||||
import net.minecraft.world.inventory.ContainerInput;
|
||||
import net.minecraft.world.inventory.ContainerListener;
|
||||
import net.minecraft.world.inventory.DataSlot;
|
||||
|
||||
@@ -26,7 +26,7 @@ public abstract class AbstractContainerMenu_scarpetMixin implements AbstractCont
|
||||
@Shadow @Final private List<DataSlot> dataSlots;
|
||||
|
||||
@Inject(method = "doClick", at = @At("HEAD"), cancellable = true)
|
||||
private void callSlotClickListener(int slotIndex, int button, ClickType actionType, Player player, CallbackInfo ci) {
|
||||
private void callSlotClickListener(int slotIndex, int button, ContainerInput actionType, Player player, CallbackInfo ci) {
|
||||
if(!(player instanceof ServerPlayer serverPlayerEntity)) return;
|
||||
for(ContainerListener screenHandlerListener : this.containerListeners) {
|
||||
if(screenHandlerListener instanceof ScreenValue.ScarpetScreenHandlerListener scarpetScreenHandlerListener) {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.AbstractContainerMenuInterface;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.AbstractCraftingMenu;
|
||||
import net.minecraft.world.inventory.RecipeBookMenu;
|
||||
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(AbstractCraftingMenu.class)
|
||||
public class AbstractCraftingMenu_scarpetMixin
|
||||
{
|
||||
@Inject(method = "handlePlacement",at = @At("HEAD"), cancellable = true)
|
||||
private void selectRecipeCallback(boolean craftAll, boolean b, RecipeHolder<?> recipe, ServerLevel serverLevel, Inventory player, CallbackInfoReturnable<RecipeBookMenu.PostPlaceAction> cir) {
|
||||
if(((AbstractContainerMenuInterface) this).callSelectRecipeListener((ServerPlayer) player.player ,recipe,craftAll))
|
||||
cir.setReturnValue(RecipeBookMenu.PostPlaceAction.NOTHING);
|
||||
}
|
||||
}
|
||||
+10
-6
@@ -1,19 +1,23 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.AbstractContainerMenuInterface;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.AbstractFurnaceMenu;
|
||||
import net.minecraft.world.inventory.RecipeBookMenu;
|
||||
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(RecipeBookMenu.class)
|
||||
public class RecipeBookMenu_scarpetMixin {
|
||||
@Mixin(AbstractFurnaceMenu.class)
|
||||
public class AbstractFurnaceMenu_scarpetMixin
|
||||
{
|
||||
@Inject(method = "handlePlacement",at = @At("HEAD"), cancellable = true)
|
||||
private void selectRecipeCallback(boolean craftAll, RecipeHolder<?> recipe, ServerPlayer player, CallbackInfo ci) {
|
||||
if(((AbstractContainerMenuInterface) this).callSelectRecipeListener(player,recipe,craftAll))
|
||||
ci.cancel();
|
||||
private void selectRecipeCallback(boolean craftAll, boolean b, RecipeHolder<?> recipe, ServerLevel level, Inventory player, CallbackInfoReturnable<RecipeBookMenu.PostPlaceAction> cir) {
|
||||
if(((AbstractContainerMenuInterface) this).callSelectRecipeListener((ServerPlayer) player.player ,recipe,craftAll))
|
||||
cir.setReturnValue(RecipeBookMenu.PostPlaceAction.NOTHING);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import carpet.fakes.EntityInterface;
|
||||
import carpet.script.EntityEventsGroup;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.vehicle.AbstractMinecart;
|
||||
import net.minecraft.world.entity.vehicle.minecart.AbstractMinecart;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
||||
@@ -29,12 +29,12 @@ public abstract class ArmorStand_scarpetMarkerMixin extends LivingEntity
|
||||
@Inject(method = "readAdditionalSaveData", at = @At("HEAD"))
|
||||
private void checkScarpetMarkerUnloaded(CallbackInfo ci)
|
||||
{
|
||||
if (!level().isClientSide)
|
||||
if (!level().isClientSide())
|
||||
{
|
||||
if (getTags().contains(Auxiliary.MARKER_STRING))
|
||||
if (entityTags().contains(Auxiliary.MARKER_STRING))
|
||||
{
|
||||
String prefix = Auxiliary.MARKER_STRING+"_";
|
||||
Optional<String> owner = getTags().stream().filter(s -> s.startsWith(prefix)).findFirst();
|
||||
Optional<String> owner = entityTags().stream().filter(s -> s.startsWith(prefix)).findFirst();
|
||||
if (owner.isPresent())
|
||||
{
|
||||
String hostName = StringUtils.removeStart(owner.get(),prefix);
|
||||
|
||||
@@ -2,8 +2,9 @@ package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.fakes.LevelInterface;
|
||||
import net.minecraft.world.level.redstone.NeighborUpdater;
|
||||
import net.minecraft.world.level.redstone.CollectingNeighborUpdater;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.redstone.Orientation;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -29,13 +30,13 @@ public class BarrierBlock_updateSuppressionBlockMixin extends Block {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level level, BlockPos pos, Block block, BlockPos fromPos, boolean notify) {
|
||||
public void neighborChanged(BlockState state, Level level, BlockPos pos, Block block, Orientation fromPos, boolean notify) {
|
||||
if (CarpetSettings.updateSuppressionBlock != -1) {
|
||||
if (fromPos.equals(pos.above())) {
|
||||
BlockState stateAbove = level.getBlockState(fromPos);
|
||||
if (true/*fromPos.equals(pos.above())*/) { // todo neighbour updates don't have source
|
||||
BlockState stateAbove = level.getBlockState(pos.above());
|
||||
if (stateAbove.is(Blocks.ACTIVATOR_RAIL) && !stateAbove.getValue(PoweredRailBlock.POWERED)) {
|
||||
level.scheduleTick(pos, this, 1);
|
||||
NeighborUpdater updater = ((LevelInterface)level).getNeighborUpdater();
|
||||
CollectingNeighborUpdater updater = ((LevelInterface)level).getNeighborUpdater();
|
||||
if (updater instanceof CollectingNeighborUpdaterAccessor cnua)
|
||||
cnua.setCount(cnua.getMaxChainedNeighborUpdates()-CarpetSettings.updateSuppressionBlock);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.BrainInterface;
|
||||
import net.minecraft.world.entity.ai.Brain;
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
|
||||
import net.minecraft.world.entity.ai.memory.MemorySlot;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(Brain.class)
|
||||
public class Brain_scarpetMixin implements BrainInterface {
|
||||
@Shadow @Final
|
||||
private Map<MemoryModuleType<?>, MemorySlot<?>> memories;
|
||||
|
||||
@Override
|
||||
public Map<MemoryModuleType<?>, MemorySlot<?>> getMemoriesCM() {
|
||||
return memories;
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,10 @@ package carpet.mixins;
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.PickaxeItem;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.level.Level;
|
||||
@@ -14,12 +14,8 @@ import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.BuddingAmethystBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.PushReaction;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(BuddingAmethystBlock.class)
|
||||
public class BuddingAmethystBlock_movableAmethystMixin extends Block {
|
||||
@@ -33,8 +29,8 @@ public class BuddingAmethystBlock_movableAmethystMixin extends Block {
|
||||
// doing it here rather than though loottables since loottables are loaded on reload
|
||||
// drawback - not controlled via loottables, but hey
|
||||
if (CarpetSettings.movableAmethyst &&
|
||||
stack.getItem() instanceof PickaxeItem &&
|
||||
EnchantmentHelper.getItemEnchantmentLevel(world.registryAccess().registryOrThrow(Registries.ENCHANTMENT).getHolderOrThrow(Enchantments.SILK_TOUCH), stack) > 0
|
||||
stack.is(ItemTags.PICKAXES) &&
|
||||
EnchantmentHelper.getItemEnchantmentLevel(world.registryAccess().lookupOrThrow(Registries.ENCHANTMENT).getOrThrow(Enchantments.SILK_TOUCH), stack) > 0
|
||||
)
|
||||
popResource(world, pos, Items.BUDDING_AMETHYST.getDefaultInstance());
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
public abstract class ChunkAccess_warningsMixin
|
||||
{
|
||||
// failed to mixin into interface. need to mixin in two places that uses it
|
||||
@Inject(method = "markPosForPostprocessing(Lnet/minecraft/core/BlockPos;)V",
|
||||
@Inject(method = "markPosForPostProcessing(Lnet/minecraft/core/BlockPos;)V",
|
||||
at =@At("HEAD"), cancellable = true)
|
||||
private void squashWarnings(BlockPos blockPos_1, CallbackInfo ci)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ package carpet.mixins;
|
||||
import carpet.utils.SpawnOverrides;
|
||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.util.random.WeightedList;
|
||||
import net.minecraft.world.level.StructureManager;
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -11,7 +12,6 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.random.WeightedRandomList;
|
||||
import net.minecraft.world.entity.MobCategory;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings;
|
||||
@@ -31,10 +31,10 @@ public abstract class ChunkGenerator_customMobSpawnsMixin
|
||||
target = "Ljava/util/Map$Entry;getKey()Ljava/lang/Object;"
|
||||
), cancellable = true)
|
||||
private void checkCMSpawns(Holder<Biome> holder, StructureManager structureFeatureManager, MobCategory mobCategory, BlockPos blockPos,
|
||||
CallbackInfoReturnable<WeightedRandomList<MobSpawnSettings.SpawnerData>> cir,
|
||||
CallbackInfoReturnable<WeightedList<MobSpawnSettings.SpawnerData>> cir,
|
||||
Map<Structure, LongSet> map, Iterator<?> var6, Map.Entry<Structure, LongSet> entry)
|
||||
{
|
||||
WeightedRandomList<MobSpawnSettings.SpawnerData> res = SpawnOverrides.test(structureFeatureManager, entry.getValue(), mobCategory, entry.getKey(), blockPos);
|
||||
WeightedList<MobSpawnSettings.SpawnerData> res = SpawnOverrides.test(structureFeatureManager, entry.getValue(), mobCategory, entry.getKey(), blockPos);
|
||||
if (res != null)
|
||||
{
|
||||
cir.setReturnValue(res);
|
||||
|
||||
@@ -9,12 +9,12 @@ import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import carpet.fakes.SimpleEntityLookupInterface;
|
||||
import carpet.fakes.ServerWorldInterface;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.TickTask;
|
||||
@@ -23,11 +23,11 @@ import net.minecraft.server.level.ChunkLevel;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ChunkMap.DistanceManager;
|
||||
import net.minecraft.server.level.ChunkResult;
|
||||
import net.minecraft.server.level.ChunkTaskPriorityQueueSorter;
|
||||
//import net.minecraft.server.level.ChunkTaskPriorityQueueSorter;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ThreadedLevelLightEngine;
|
||||
import net.minecraft.server.level.TicketType;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||
|
||||
import net.minecraft.util.thread.BlockableEventLoop;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -46,7 +46,6 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import carpet.fakes.ChunkHolderInterface;
|
||||
import carpet.fakes.ChunkTicketManagerInterface;
|
||||
import carpet.fakes.ServerLightingProviderInterface;
|
||||
import carpet.fakes.ThreadedAnvilChunkStorageInterface;
|
||||
import carpet.script.utils.WorldTools;
|
||||
@@ -76,17 +75,17 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
@Final
|
||||
private ThreadedLevelLightEngine lightEngine;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private ChunkTaskPriorityQueueSorter queueSorter;
|
||||
//@Shadow
|
||||
//@Final
|
||||
//private ChunkTaskPriorityQueueSorter queueSorter;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private BlockableEventLoop<Runnable> mainThreadExecutor;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private ChunkProgressListener progressListener;
|
||||
//@Shadow
|
||||
//@Final
|
||||
//private ChunkProgressListener progressListener;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
@@ -95,8 +94,8 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
@Shadow
|
||||
protected abstract boolean promoteChunkMap();
|
||||
|
||||
@Shadow
|
||||
protected abstract Iterable<ChunkHolder> getChunks();
|
||||
//@Shadow
|
||||
//protected abstract void forEachReadyToSendChunk(Consumer<LevelChunk> consumer); // for getChunks()
|
||||
|
||||
|
||||
@Shadow
|
||||
@@ -165,7 +164,6 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
this.world.getServer().execute(() -> CHUNK_LOADED.onChunkEvent(this.world, chpos, generated));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@Unique
|
||||
private void addTicket(ChunkPos pos, ChunkStatus status)
|
||||
@@ -180,7 +178,6 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@Unique
|
||||
private void addRelightTicket(ChunkPos pos)
|
||||
{
|
||||
@@ -195,7 +192,7 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
() -> "release relight ticket " + pos
|
||||
));
|
||||
}
|
||||
*/
|
||||
|
||||
@Unique
|
||||
private void tickTicketManager()
|
||||
{
|
||||
@@ -220,7 +217,7 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@Unique
|
||||
private Set<ChunkPos> loadExistingChunksFromDisk(Set<ChunkPos> requestedChunks)
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ public abstract class ClientPacketListener_clientCommandMixin extends ClientComm
|
||||
if (CarpetServer.minecraft_server == null && !CarpetClient.isCarpet() && minecraft.player != null)
|
||||
{
|
||||
LocalPlayer playerSource = minecraft.player;
|
||||
CarpetServer.forEachManager(sm -> sm.inspectClientsideCommand(playerSource.createCommandSourceStack(), "/" + string));
|
||||
CarpetServer.forEachManager(sm -> sm.inspectClientsideCommand("/" + string));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import net.minecraft.client.multiplayer.CommonListenerCookie;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.protocol.game.ClientboundExplodePacket;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
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(ClientPacketListener.class)
|
||||
public abstract class ClientPacketListener_explosionMixin extends ClientCommonPacketListenerImpl
|
||||
{
|
||||
|
||||
private static Vec3 vec3dmem;
|
||||
private static long tickmem;
|
||||
// For disabling the explosion particles and sounds if explosions are stacking up
|
||||
|
||||
protected ClientPacketListener_explosionMixin(final Minecraft minecraft, final Connection connection, final CommonListenerCookie commonListenerCookie)
|
||||
{
|
||||
super(minecraft, connection, commonListenerCookie);
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "handleExplosion", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/multiplayer/ClientLevel;playLocalSound(DDDLnet/minecraft/sounds/SoundEvent;Lnet/minecraft/sounds/SoundSource;FFZ)V"
|
||||
), cancellable = true)
|
||||
private void onHandleExplosion(final ClientboundExplodePacket clientboundExplodePacket, final CallbackInfo ci)
|
||||
{
|
||||
|
||||
if (CarpetSettings.optimizedTNT)
|
||||
{
|
||||
Vec3 vec3d = clientboundExplodePacket.center();
|
||||
long tick = minecraft.level.getGameTime();
|
||||
if (vec3dmem == null || !vec3dmem.equals(vec3d) || tickmem != tick) {
|
||||
vec3dmem = vec3d;
|
||||
tickmem = tick;
|
||||
} else {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.commands.CloneCommands;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
@@ -14,10 +15,10 @@ public abstract class CloneCommands_fillUpdatesMixin
|
||||
{
|
||||
@Redirect(method = "clone", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/server/level/ServerLevel;blockUpdated(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;)V"
|
||||
target = "Lnet/minecraft/server/level/ServerLevel;updateNeighboursOnBlockSet(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)V"
|
||||
))
|
||||
private static void conditionalUpdating(ServerLevel serverWorld, BlockPos blockPos_1, Block block_1)
|
||||
private static void conditionalUpdating(ServerLevel serverWorld, BlockPos blockPos_1, BlockState block_1)
|
||||
{
|
||||
if (CarpetSettings.fillUpdates) serverWorld.blockUpdated(blockPos_1, block_1);
|
||||
if (CarpetSettings.fillUpdates) serverWorld.updateNeighboursOnBlockSet(blockPos_1, block_1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.CommandSourceStackInterface;
|
||||
import net.minecraft.commands.CommandResultCallback;
|
||||
import net.minecraft.commands.CommandSigningContext;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.arguments.EntityAnchorArgument;
|
||||
import net.minecraft.util.TaskChainer;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(CommandSourceStack.class)
|
||||
public class CommandSourceStack_scarpetMixin implements CommandSourceStackInterface {
|
||||
@Mutable @Shadow private boolean silent;
|
||||
@Mutable @Shadow private CommandResultCallback resultCallback;
|
||||
@Mutable @Shadow private EntityAnchorArgument.Anchor anchor;
|
||||
@Mutable @Shadow private CommandSigningContext signingContext;
|
||||
@Mutable @Shadow private TaskChainer chatMessageChainer;
|
||||
|
||||
@Override
|
||||
public void setupPrivates(boolean bl, CommandResultCallback commandResultCallback, EntityAnchorArgument.Anchor anchor, CommandSigningContext commandSigningContext, TaskChainer taskChainer) {
|
||||
this.silent = bl;
|
||||
this.resultCallback = commandResultCallback;
|
||||
this.anchor = anchor;
|
||||
this.signingContext = commandSigningContext;
|
||||
this.chatMessageChainer = taskChainer;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package carpet.mixins;
|
||||
import carpet.fakes.ClientConnectionInterface;
|
||||
import carpet.logging.logHelpers.PacketCounter;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.util.concurrent.Future;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
@@ -28,7 +29,7 @@ public abstract class Connection_packetCounterMixin implements ClientConnectionI
|
||||
|
||||
// Add to the packet counter whenever a packet is sent.
|
||||
@Inject(method = "sendPacket", at = @At("HEAD"))
|
||||
private void packetOutCount(final Packet<?> packet, final PacketSendListener packetSendListener, final boolean bl, final CallbackInfo ci)
|
||||
private void packetOutCount(Packet<?> packet, ChannelFutureListener channelFutureListener, boolean bl, CallbackInfo ci)
|
||||
{
|
||||
PacketCounter.totalOut++;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@Mixin(DebugRenderer.class)
|
||||
public class DebugRenderer_scarpetRenderMixin
|
||||
{
|
||||
@Inject(method = "clear", at = @At("HEAD"))
|
||||
@Inject(method = "refreshRendererList", at = @At("HEAD"))
|
||||
private void resetScarpetRenderes(CallbackInfo ci)
|
||||
{
|
||||
if (CarpetClient.shapes != null)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.DefaultRedstoneWireEvaluatorInferface;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.redstone.DefaultRedstoneWireEvaluator;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(DefaultRedstoneWireEvaluator.class)
|
||||
public abstract class DefaultRedstoneWireEvaluator_redstoneMixin implements DefaultRedstoneWireEvaluatorInferface
|
||||
{
|
||||
@Shadow protected abstract int calculateTargetStrength(final Level level, final BlockPos blockPos);
|
||||
|
||||
@Override
|
||||
public int calculateTargetStrengthCM(final Level level, final BlockPos pos)
|
||||
{
|
||||
return calculateTargetStrength(level, pos);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import net.minecraft.world.level.redstone.Orientation;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
@@ -23,7 +24,7 @@ public class DispenserBlock_qcMixin {
|
||||
target = "Lnet/minecraft/world/level/Level;hasNeighborSignal(Lnet/minecraft/core/BlockPos;)Z"
|
||||
)
|
||||
)
|
||||
private boolean carpet_hasQuasiSignal(Level _level, BlockPos above, BlockState state, Level level, BlockPos pos, Block neighborBlock, BlockPos neighborPos, boolean movedByPiston) {
|
||||
private boolean carpet_hasQuasiSignal(Level _level, BlockPos above, BlockState state, Level level, BlockPos pos, Block neighborBlock, Orientation neighborPos, boolean movedByPiston) {
|
||||
return QuasiConnectivity.hasQuasiSignal(level, pos);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import java.util.Set;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
import net.minecraft.server.level.DistanceManager;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import carpet.fakes.ChunkTicketManagerInterface;
|
||||
|
||||
@Mixin(DistanceManager.class)
|
||||
public abstract class DistanceManager_scarpetChunkCreationMixin implements ChunkTicketManagerInterface
|
||||
{
|
||||
@Shadow
|
||||
@Final
|
||||
private Set<ChunkHolder> chunksToUpdateFutures;
|
||||
|
||||
@Override
|
||||
public void replaceHolder(final ChunkHolder oldHolder, final ChunkHolder newHolder)
|
||||
{
|
||||
this.chunksToUpdateFutures.remove(oldHolder);
|
||||
this.chunksToUpdateFutures.add(newHolder);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,25 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.ChunkTicketManagerInterface;
|
||||
import carpet.fakes.TicketsFetcherInterface;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import net.minecraft.server.level.DistanceManager;
|
||||
import net.minecraft.server.level.Ticket;
|
||||
import net.minecraft.util.SortedArraySet;
|
||||
import net.minecraft.world.level.TicketStorage;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(DistanceManager.class)
|
||||
public abstract class DistanceManager_scarpetMixin implements ChunkTicketManagerInterface
|
||||
public abstract class DistanceManager_scarpetMixin implements TicketsFetcherInterface
|
||||
{
|
||||
@Shadow @Final private Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> tickets;
|
||||
@Shadow @Final private TicketStorage ticketStorage;
|
||||
|
||||
@Override
|
||||
public Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> getTicketsByPosition()
|
||||
public Long2ObjectOpenHashMap<List<Ticket>> getTicketsByPosition()
|
||||
{
|
||||
return tickets;
|
||||
return ((TicketsFetcherInterface)ticketStorage).getTicketsByPosition();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.ChunkTicketManagerInterface;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import net.minecraft.server.level.DistanceManager;
|
||||
import net.minecraft.server.level.Ticket;
|
||||
import net.minecraft.server.level.TicketType;
|
||||
import net.minecraft.util.SortedArraySet;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
@Mixin(DistanceManager.class)
|
||||
public abstract class DistanceManager_spawnChunksMixin implements ChunkTicketManagerInterface
|
||||
{
|
||||
@Shadow @Final private Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> tickets;
|
||||
|
||||
@Shadow protected abstract void removeTicket(long pos, Ticket<?> ticket);
|
||||
|
||||
@Shadow public abstract <T> void addRegionTicket(TicketType<T> type, ChunkPos pos, int radius, T argument);
|
||||
|
||||
@Override
|
||||
public void changeSpawnChunks(ChunkPos chunkPos, int distance)
|
||||
{
|
||||
long pos = chunkPos.toLong();
|
||||
SortedArraySet<Ticket<?>> set = tickets.get(pos);
|
||||
Ticket<?> existingTicket = null;
|
||||
if (set != null)
|
||||
{
|
||||
Iterator<Ticket<?>> iter = set.iterator();
|
||||
while(iter.hasNext())
|
||||
{
|
||||
Ticket<?> ticket = iter.next();
|
||||
if (ticket.getType() == TicketType.START)
|
||||
{
|
||||
existingTicket = ticket;
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
set.add(existingTicket);
|
||||
}
|
||||
// the reason we are removing the ticket this way is that there are sideeffects of removal
|
||||
if (existingTicket != null)
|
||||
{
|
||||
removeTicket(pos, existingTicket);
|
||||
}
|
||||
// set optionally new spawn ticket
|
||||
if (distance > 0)
|
||||
addRegionTicket(TicketType.START, chunkPos, distance, Unit.INSTANCE);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,9 @@ import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@@ -32,9 +35,19 @@ public abstract class EntityMixin implements EntityInterface
|
||||
return partialTicks == 1.0F ? this.yRot : Mth.lerp(partialTicks, this.yRotO, this.yRot);
|
||||
}
|
||||
|
||||
@Inject(method = "isControlledByLocalInstance", at = @At("HEAD"), cancellable = true)
|
||||
@Inject(method = "isLocalInstanceAuthoritative", at = @At("HEAD"), cancellable = true)
|
||||
private void isFakePlayer(CallbackInfoReturnable<Boolean> cir)
|
||||
{
|
||||
if (getControllingPassenger() instanceof EntityPlayerMPFake) cir.setReturnValue(!level.isClientSide);
|
||||
// getControllingPassenger() does not return the EntityPlayerMPFake if there are no passengers involved with it
|
||||
if ((Object) this instanceof EntityPlayerMPFake || getControllingPassenger() instanceof EntityPlayerMPFake) cir.setReturnValue(!level.isClientSide());
|
||||
}
|
||||
|
||||
@Shadow
|
||||
protected abstract Stream<Entity> getIndirectPassengersStream();
|
||||
|
||||
@Override
|
||||
public Stream<Entity> cm$getIndirectPassengersStream()
|
||||
{
|
||||
return this.getIndirectPassengersStream();
|
||||
}
|
||||
}
|
||||
@@ -19,9 +19,6 @@ public abstract class ExperienceOrb_xpNoCooldownMixin extends Entity
|
||||
@Shadow
|
||||
private int count;
|
||||
|
||||
@Shadow
|
||||
private int value;
|
||||
|
||||
public ExperienceOrb_xpNoCooldownMixin(EntityType<?> type, Level world)
|
||||
{
|
||||
super(type, world);
|
||||
@@ -30,13 +27,15 @@ public abstract class ExperienceOrb_xpNoCooldownMixin extends Entity
|
||||
@Shadow
|
||||
protected abstract int repairPlayerItems(ServerPlayer player, int amount);
|
||||
|
||||
@Shadow public abstract int getValue();
|
||||
|
||||
@Inject(method = "playerTouch", at = @At("HEAD"))
|
||||
private void addXP(Player player, CallbackInfo ci) {
|
||||
if (CarpetSettings.xpNoCooldown && !level().isClientSide) {
|
||||
if (CarpetSettings.xpNoCooldown && !level().isClientSide()) {
|
||||
player.takeXpDelay = 0;
|
||||
// reducing the count to 1 and leaving vanilla to deal with it
|
||||
while (this.count > 1) {
|
||||
int remainder = this.repairPlayerItems((ServerPlayer) player, this.value);
|
||||
int remainder = this.repairPlayerItems((ServerPlayer) player, this.getValue());
|
||||
if (remainder > 0) {
|
||||
player.giveExperiencePoints(remainder);
|
||||
}
|
||||
|
||||
@@ -1,37 +1,22 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.level.ServerExplosion;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
@Mixin(Explosion.class)
|
||||
@Mixin(ServerExplosion.class)
|
||||
public interface ExplosionAccessor {
|
||||
|
||||
@Accessor
|
||||
boolean isFire();
|
||||
ServerLevel getLevel();
|
||||
|
||||
@Accessor
|
||||
Explosion.BlockInteraction getBlockInteraction();
|
||||
|
||||
@Accessor
|
||||
Level getLevel();
|
||||
|
||||
@Accessor
|
||||
RandomSource getRandom();
|
||||
|
||||
@Accessor
|
||||
double getX();
|
||||
|
||||
@Accessor
|
||||
double getY();
|
||||
|
||||
@Accessor
|
||||
double getZ();
|
||||
Vec3 getCenter();
|
||||
|
||||
@Accessor
|
||||
float getRadius();
|
||||
|
||||
@@ -4,11 +4,12 @@ import carpet.helpers.OptimizedExplosion;
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.logging.LoggerRegistry;
|
||||
import carpet.logging.logHelpers.ExplosionLogHelper;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.monster.breeze.Breeze;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.ServerExplosion;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -23,81 +24,74 @@ import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.ExplosionDamageCalculator;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(value = Explosion.class)
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Mixin(value = ServerExplosion.class)
|
||||
public abstract class Explosion_optimizedTntMixin
|
||||
{
|
||||
@Shadow
|
||||
@Final
|
||||
private ObjectArrayList<BlockPos> toBlow;
|
||||
|
||||
@Shadow @Final private Level level;
|
||||
@Shadow @Final private ServerLevel level;
|
||||
|
||||
@Shadow @Nullable public abstract LivingEntity getIndirectSourceEntity();
|
||||
|
||||
private ExplosionLogHelper eLogger;
|
||||
|
||||
@Inject(method = "explode", at = @At("HEAD"),
|
||||
@Inject(method = "calculateExplodedPositions", at = @At("HEAD"),
|
||||
cancellable = true)
|
||||
private void onExplosionA(CallbackInfo ci)
|
||||
private void calculateExplodedPositionsCM(final CallbackInfoReturnable<List<BlockPos>> cir)
|
||||
{
|
||||
if (CarpetSettings.optimizedTNT && !level.isClientSide && !(getIndirectSourceEntity() instanceof Breeze))
|
||||
if (CarpetSettings.optimizedTNT && !level.isClientSide() && !(getIndirectSourceEntity() instanceof Breeze))
|
||||
{
|
||||
OptimizedExplosion.doExplosionA((Explosion) (Object) this, eLogger);
|
||||
ci.cancel();
|
||||
cir.setReturnValue(OptimizedExplosion.doExplosionA((Explosion) (Object) this, eLogger));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "finalizeExplosion", at = @At("HEAD"),
|
||||
cancellable = true)
|
||||
private void onExplosionB(boolean spawnParticles, CallbackInfo ci)
|
||||
@Inject(method = "interactWithBlocks", at = @At("HEAD"))
|
||||
private void interactWithBlocksCM(final List<BlockPos> list, final CallbackInfo ci)
|
||||
{
|
||||
if (eLogger != null)
|
||||
{
|
||||
eLogger.setAffectBlocks( ! toBlow.isEmpty());
|
||||
eLogger.setAffectBlocks( ! list.isEmpty());
|
||||
eLogger.onExplosionDone(this.level.getGameTime());
|
||||
}
|
||||
if (CarpetSettings.explosionNoBlockDamage)
|
||||
{
|
||||
toBlow.clear();
|
||||
}
|
||||
if (CarpetSettings.optimizedTNT && !level.isClientSide && !(getIndirectSourceEntity() instanceof Breeze))
|
||||
{
|
||||
OptimizedExplosion.doExplosionB((Explosion) (Object) this, spawnParticles);
|
||||
ci.cancel();
|
||||
list.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//optional due to Overwrite in Lithium
|
||||
//should kill most checks if no block damage is requested
|
||||
@Redirect(method = "explode", require = 0, at = @At(value = "INVOKE",
|
||||
target ="Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;"))
|
||||
private BlockState noBlockCalcsWithNoBLockDamage(Level world, BlockPos pos)
|
||||
@Redirect(method = "calculateExplodedPositions", require = 0, at = @At(value = "INVOKE",
|
||||
target ="Lnet/minecraft/world/level/ExplosionDamageCalculator;getBlockExplosionResistance(Lnet/minecraft/world/level/Explosion;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/material/FluidState;)Ljava/util/Optional;"))
|
||||
private Optional<Float> noBlockCalcsWithNoBLockDamage(final ExplosionDamageCalculator instance, final Explosion explosion, final BlockGetter blockGetter, final BlockPos blockPos, final BlockState blockState, final FluidState fluidState)
|
||||
{
|
||||
if (CarpetSettings.explosionNoBlockDamage) return Blocks.BEDROCK.defaultBlockState();
|
||||
return world.getBlockState(pos);
|
||||
if (CarpetSettings.explosionNoBlockDamage) return Optional.of(Blocks.BEDROCK.getExplosionResistance());
|
||||
return instance.getBlockExplosionResistance(explosion, blockGetter, blockPos, blockState, fluidState);
|
||||
}
|
||||
|
||||
@Inject(method = "<init>(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/damagesource/DamageSource;Lnet/minecraft/world/level/ExplosionDamageCalculator;DDDFZLnet/minecraft/world/level/Explosion$BlockInteraction;Lnet/minecraft/core/particles/ParticleOptions;Lnet/minecraft/core/particles/ParticleOptions;Lnet/minecraft/core/Holder;)V",
|
||||
@Inject(method = "<init>",
|
||||
at = @At(value = "RETURN"))
|
||||
private void onExplosionCreated(Level world, Entity entity, DamageSource damageSource, ExplosionDamageCalculator explosionBehavior, double x, double y, double z, float power, boolean createFire, Explosion.BlockInteraction destructionType, ParticleOptions particleOptions, ParticleOptions particleOptions2, Holder soundEvent, CallbackInfo ci)
|
||||
private void onExplostion(ServerLevel world, Entity entity, DamageSource damageSource, final ExplosionDamageCalculator explosionBehavior, final Vec3 vec3, final float power, final boolean createFire, final Explosion.BlockInteraction destructionType, final CallbackInfo ci)
|
||||
{
|
||||
if (LoggerRegistry.__explosions && ! world.isClientSide)
|
||||
if (LoggerRegistry.__explosions && ! world.isClientSide())
|
||||
{
|
||||
eLogger = new ExplosionLogHelper(x, y, z, power, createFire, destructionType, level.registryAccess());
|
||||
eLogger = new ExplosionLogHelper(vec3.x, vec3.y, vec3.z, power, createFire, destructionType, level.registryAccess());
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(method = "explode",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;setDeltaMovement(Lnet/minecraft/world/phys/Vec3;)V"))
|
||||
@Redirect(method = "hurtEntities",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;push(Lnet/minecraft/world/phys/Vec3;)V"))
|
||||
private void setVelocityAndUpdateLogging(Entity entity, Vec3 velocity)
|
||||
{
|
||||
if (eLogger != null) {
|
||||
eLogger.onEntityImpacted(entity, velocity.subtract(entity.getDeltaMovement()));
|
||||
}
|
||||
entity.setDeltaMovement(velocity);
|
||||
entity.push(velocity);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.world.level.ServerExplosion;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -10,70 +8,52 @@ 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.server.level.ServerLevel;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.ExplosionDamageCalculator;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import static carpet.script.CarpetEventServer.Event.EXPLOSION_OUTCOME;
|
||||
|
||||
@Mixin(value = Explosion.class, priority = 990)
|
||||
@Mixin(value = ServerExplosion.class, priority = 990)
|
||||
public abstract class Explosion_scarpetEventMixin
|
||||
{
|
||||
@Shadow @Final private Level level;
|
||||
@Shadow @Final private double x;
|
||||
@Shadow @Final private double y;
|
||||
@Shadow @Final private double z;
|
||||
@Shadow @Final private ServerLevel level;
|
||||
@Shadow @Final private Vec3 center;
|
||||
@Shadow @Final private float radius;
|
||||
@Shadow @Final private boolean fire;
|
||||
@Shadow @Final private ObjectArrayList<BlockPos> toBlow;
|
||||
@Shadow @Final private Explosion.BlockInteraction blockInteraction;
|
||||
@Shadow @Final private @Nullable Entity source;
|
||||
|
||||
@Shadow /*@Nullable*/ public abstract /*@Nullable*/ LivingEntity getIndirectSourceEntity();
|
||||
|
||||
@Shadow public static float getSeenPercent(Vec3 source, Entity entity) {return 0.0f;}
|
||||
private List<Entity> affectedEntities = new ArrayList<>();
|
||||
|
||||
private List<Entity> affectedEntities;
|
||||
|
||||
@Inject(method = "<init>(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/damagesource/DamageSource;Lnet/minecraft/world/level/ExplosionDamageCalculator;DDDFZLnet/minecraft/world/level/Explosion$BlockInteraction;Lnet/minecraft/core/particles/ParticleOptions;Lnet/minecraft/core/particles/ParticleOptions;Lnet/minecraft/core/Holder;)V",
|
||||
at = @At(value = "RETURN"))
|
||||
private void onExplosionCreated(Level world, Entity entity, DamageSource damageSource, ExplosionDamageCalculator explosionBehavior, double x, double y, double z, float power, boolean createFire, Explosion.BlockInteraction destructionType, ParticleOptions particleOptions, ParticleOptions particleOptions2, Holder soundEvent, CallbackInfo ci)
|
||||
@Inject(method = "explode", at = @At("HEAD"))
|
||||
private void explodeCM(CallbackInfoReturnable<Integer> cir)
|
||||
{
|
||||
if (EXPLOSION_OUTCOME.isNeeded() && !world.isClientSide())
|
||||
{
|
||||
affectedEntities = new ArrayList<>();
|
||||
}
|
||||
affectedEntities.clear();
|
||||
}
|
||||
|
||||
@Redirect(method = "explode", at=@At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/Explosion;getSeenPercent(Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/entity/Entity;)F")
|
||||
)
|
||||
private float onExplosion(Vec3 source, Entity entity)
|
||||
@Redirect(method = "hurtEntities", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;onExplosionHit(Lnet/minecraft/world/entity/Entity;)V"))
|
||||
private void onEntityHit(Entity instance, Entity entity)
|
||||
{
|
||||
if (affectedEntities != null)
|
||||
{
|
||||
affectedEntities.add(entity);
|
||||
}
|
||||
return getSeenPercent(source, entity);
|
||||
affectedEntities.add(instance);
|
||||
instance.onExplosionHit(entity);
|
||||
}
|
||||
|
||||
@Inject(method = "finalizeExplosion", at = @At("HEAD"))
|
||||
private void onExplosion(boolean spawnParticles, CallbackInfo ci)
|
||||
@Inject(method = "explode", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/ServerExplosion;hurtEntities()V", shift = At.Shift.AFTER))
|
||||
private void onExplosionDone(CallbackInfoReturnable<Integer> cir, List list)
|
||||
{
|
||||
if (EXPLOSION_OUTCOME.isNeeded() && !level.isClientSide())
|
||||
{
|
||||
EXPLOSION_OUTCOME.onExplosion((ServerLevel) level, source, this::getIndirectSourceEntity, x, y, z, radius, fire, toBlow, affectedEntities, blockInteraction);
|
||||
EXPLOSION_OUTCOME.onExplosion((ServerLevel) level, source, this::getIndirectSourceEntity, center, radius, fire, list, affectedEntities, blockInteraction);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ public abstract class FallingBlockEntityMixin extends Entity
|
||||
@Inject(method = "<init>(Lnet/minecraft/world/entity/EntityType;Lnet/minecraft/world/level/Level;)V", at = @At("RETURN"))
|
||||
private void addLogger(EntityType<? extends Projectile> entityType_1, Level world_1, CallbackInfo ci)
|
||||
{
|
||||
if (LoggerRegistry.__fallingBlocks && !world_1.isClientSide)
|
||||
if (LoggerRegistry.__fallingBlocks && !world_1.isClientSide())
|
||||
logHelper = new TrajectoryLogHelper("fallingBlocks");
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.commands.FillCommand;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
@@ -14,10 +15,10 @@ public abstract class FillCommandMixin
|
||||
{
|
||||
@Redirect(method = "fillBlocks", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/server/level/ServerLevel;blockUpdated(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;)V"
|
||||
target = "Lnet/minecraft/server/level/ServerLevel;updateNeighboursOnBlockSet(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)V"
|
||||
))
|
||||
private static void conditionalUpdating(ServerLevel serverWorld, BlockPos blockPos_1, Block block_1)
|
||||
private static void conditionalUpdating(ServerLevel serverWorld, BlockPos blockPos_1, BlockState block_1)
|
||||
{
|
||||
if (CarpetSettings.fillUpdates) serverWorld.blockUpdated(blockPos_1, block_1);
|
||||
if (CarpetSettings.fillUpdates) serverWorld.updateNeighboursOnBlockSet(blockPos_1, block_1);
|
||||
}
|
||||
}
|
||||
@@ -16,14 +16,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
public class FlowingFluid_liquidDamageDisabledMixin
|
||||
{
|
||||
@Inject(
|
||||
method = "canHoldFluid",
|
||||
method = "canHoldAnyFluid",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/block/state/BlockState;blocksMotion()Z"
|
||||
),
|
||||
cancellable = true
|
||||
)
|
||||
private void stopBreakingBlock(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid, CallbackInfoReturnable<Boolean> cir)
|
||||
private static void stopBreakingBlock(final BlockState state, final CallbackInfoReturnable<Boolean> cir)
|
||||
{
|
||||
if (CarpetSettings.liquidDamageDisabled)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.FoodDataInterface;
|
||||
import net.minecraft.world.food.FoodData;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(FoodData.class)
|
||||
public class FoodData_scarpetMixin implements FoodDataInterface
|
||||
{
|
||||
@Shadow private float exhaustionLevel;
|
||||
|
||||
@Override
|
||||
public float getCMExhaustionLevel()
|
||||
{
|
||||
return exhaustionLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExhaustion(float aFloat)
|
||||
{
|
||||
exhaustionLevel = aFloat;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.EntityTypes;
|
||||
import net.minecraft.world.entity.LightningBolt;
|
||||
import net.minecraft.world.entity.MobSpawnType;
|
||||
import net.minecraft.world.entity.SpawnGroupData;
|
||||
import net.minecraft.world.entity.monster.ElderGuardian;
|
||||
import net.minecraft.world.entity.monster.Guardian;
|
||||
import net.minecraft.world.entity.monster.Monster;
|
||||
@@ -24,11 +23,11 @@ public abstract class Guardian_renewableSpongesMixin extends Monster
|
||||
@Override
|
||||
public void thunderHit(ServerLevel serverWorld, LightningBolt lightningEntity)
|
||||
{ // isRemoved()
|
||||
if (!this.level().isClientSide && !this.isRemoved() && CarpetSettings.renewableSponges && !((Object)this instanceof ElderGuardian))
|
||||
if (!this.level().isClientSide() && !this.isRemoved() && CarpetSettings.renewableSponges && !((Object)this instanceof ElderGuardian))
|
||||
{
|
||||
ElderGuardian elderGuardian = new ElderGuardian(EntityType.ELDER_GUARDIAN ,this.level());
|
||||
elderGuardian.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());
|
||||
elderGuardian.finalizeSpawn(serverWorld ,this.level().getCurrentDifficultyAt(elderGuardian.blockPosition()), MobSpawnType.CONVERSION, null);
|
||||
ElderGuardian elderGuardian = new ElderGuardian(EntityTypes.ELDER_GUARDIAN ,this.level());
|
||||
elderGuardian.snapTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());
|
||||
elderGuardian.finalizeSpawn(serverWorld ,serverWorld.getCurrentDifficultyAt(elderGuardian.blockPosition()), EntitySpawnReason.CONVERSION, null);
|
||||
elderGuardian.setNoAi(this.isNoAi());
|
||||
|
||||
if (this.hasCustomName())
|
||||
|
||||
@@ -3,6 +3,7 @@ package carpet.mixins;
|
||||
import carpet.fakes.PlayerListHudInterface;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.gui.Hud;
|
||||
import net.minecraft.client.gui.components.PlayerTabOverlay;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -10,7 +11,7 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(Gui.class)
|
||||
@Mixin(Hud.class)
|
||||
public abstract class Gui_tablistMixin
|
||||
{
|
||||
@Shadow
|
||||
@@ -19,7 +20,7 @@ public abstract class Gui_tablistMixin
|
||||
|
||||
@Shadow @Final private PlayerTabOverlay tabList;
|
||||
|
||||
@Redirect(method = "renderTabList", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;isLocalServer()Z"))
|
||||
@Redirect(method = "extractTabList", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;isLocalServer()Z"))
|
||||
private boolean onDraw(Minecraft minecraftClient)
|
||||
{
|
||||
return this.minecraft.isLocalServer() && !((PlayerListHudInterface) tabList).hasFooterOrHeader();
|
||||
|
||||
@@ -3,7 +3,7 @@ package carpet.mixins;
|
||||
import carpet.fakes.InventoryBearerInterface;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.entity.animal.horse.AbstractHorse;
|
||||
import net.minecraft.world.entity.animal.equine.AbstractHorse;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.utils.SpawnOverrides;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.monster.Husk;
|
||||
import net.minecraft.world.level.ServerLevelAccessor;
|
||||
import net.minecraft.world.level.levelgen.structure.BuiltinStructures;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(Husk.class)
|
||||
public class Husk_templesMixin
|
||||
{
|
||||
@Redirect(method = "checkHuskSpawnRules", at = @At(value = "INVOKE", target="Lnet/minecraft/world/level/ServerLevelAccessor;canSeeSky(Lnet/minecraft/core/BlockPos;)Z"))
|
||||
private static boolean isSkylightOrTempleVisible(ServerLevelAccessor serverWorldAccess, BlockPos pos)
|
||||
{
|
||||
return serverWorldAccess.canSeeSky(pos) ||
|
||||
(CarpetSettings.huskSpawningInTemples && SpawnOverrides.isStructureAtPosition((ServerLevel)serverWorldAccess, BuiltinStructures.DESERT_PYRAMID, pos));
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,11 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.IngredientInterface;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
|
||||
@Mixin(Ingredient.class)
|
||||
public class Ingredient_scarpetMixin implements IngredientInterface
|
||||
public class Ingredient_scarpetMixin// implements IngredientInterface
|
||||
{
|
||||
@Shadow @Final private Ingredient.Value[] values;
|
||||
|
||||
@Override
|
||||
public List<Collection<ItemStack>> getRecipeStacks()
|
||||
{
|
||||
return Arrays.stream(values).map(Ingredient.Value::getItems).toList();
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package carpet.mixins;
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.ItemInstance;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.component.ItemContainerContents;
|
||||
import net.minecraft.world.level.block.ShulkerBoxBlock;
|
||||
@@ -11,16 +12,17 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(ItemStack.class)
|
||||
public class ItemStack_stackableShulkerBoxesMixin
|
||||
@Mixin(ItemInstance.class)
|
||||
public interface ItemStack_stackableShulkerBoxesMixin
|
||||
{
|
||||
@Inject(method = "getMaxStackSize", at = @At("HEAD"), cancellable = true)
|
||||
private void getCMMAxStackSize(CallbackInfoReturnable<Integer> cir)
|
||||
{
|
||||
if (CarpetSettings.shulkerBoxStackSize > 1
|
||||
&& ((ItemStack)((Object)this)).getItem() instanceof BlockItem blockItem
|
||||
&& ((ItemInstance)((Object)this)) instanceof final ItemStack itemStack
|
||||
&& itemStack.getItem() instanceof BlockItem blockItem
|
||||
&& blockItem.getBlock() instanceof ShulkerBoxBlock
|
||||
&& ((ItemStack) ((Object) this)).getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY).stream().findAny().isEmpty()
|
||||
&& ((ItemStack) ((Object) this)).getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY).allItemsCopyStream().findAny().isEmpty()
|
||||
) {
|
||||
cir.setReturnValue(CarpetSettings.shulkerBoxStackSize);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.component.Tool;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(Item.class)
|
||||
public class Item_missingToolsMixin
|
||||
{
|
||||
@Inject(method = "getDestroySpeed", at = @At("HEAD"), cancellable = true)
|
||||
public void getDestroySpeed(ItemStack itemStack, BlockState blockState, CallbackInfoReturnable<Float> cir) {
|
||||
if (CarpetSettings.missingTools && blockState.getSoundType() == SoundType.GLASS && itemStack.is(ItemTags.PICKAXES))
|
||||
{
|
||||
Tool tool = itemStack.get(DataComponents.TOOL);
|
||||
if (tool != null) {
|
||||
cir.setReturnValue(tool.getMiningSpeed(Blocks.STONE.defaultBlockState()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,9 @@ package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -25,20 +27,25 @@ public class LevelChunk_fillUpdatesMixin
|
||||
|
||||
@Redirect(method = "setBlockState", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/block/state/BlockState;onRemove(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Z)V"
|
||||
target = "Lnet/minecraft/world/level/block/entity/BlockEntity;preRemoveSideEffects(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)V"
|
||||
))
|
||||
private void onRemovedBlock(BlockState blockState, Level world, BlockPos pos, BlockState state, boolean moved)
|
||||
private void onPreRemoveSideEffects(BlockEntity blockEntity, BlockPos blockPos_1, BlockState blockState_1)
|
||||
{
|
||||
if (CarpetSettings.impendingFillSkipUpdates.get()) // doing due dilligence from AbstractBlock onStateReplaced
|
||||
if (!CarpetSettings.impendingFillSkipUpdates.get())
|
||||
{
|
||||
if (blockState.hasBlockEntity() && !blockState.is(state.getBlock()))
|
||||
{
|
||||
world.removeBlockEntity(pos);
|
||||
}
|
||||
blockEntity.preRemoveSideEffects(blockPos_1, blockState_1);
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
@Redirect(method = "setBlockState", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/block/state/BlockState;affectNeighborsAfterRemoval(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;Z)V"
|
||||
))
|
||||
private void onAffectNeighborsAfterRemoval(final BlockState instance, final ServerLevel serverLevel, final BlockPos blockPos, final boolean b)
|
||||
{
|
||||
if (!CarpetSettings.impendingFillSkipUpdates.get())
|
||||
{
|
||||
blockState.onRemove(world, pos, state, moved);
|
||||
instance.affectNeighborsAfterRemoval(serverLevel, blockPos, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,21 +4,24 @@ import carpet.CarpetSettings;
|
||||
import carpet.fakes.WorldChunkInterface;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.profiling.Profiler;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelHeightAccessor;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.BaseRailBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.EntityBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.piston.MovingPistonBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
import net.minecraft.world.level.chunk.UpgradeData;
|
||||
import net.minecraft.world.level.chunk.*;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.levelgen.blending.BlendingData;
|
||||
import net.minecraft.world.level.lighting.LightEngine;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -33,8 +36,8 @@ public abstract class LevelChunk_movableBEMixin extends ChunkAccess implements W
|
||||
@Final
|
||||
Level level;
|
||||
|
||||
public LevelChunk_movableBEMixin(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor heightLimitView, Registry<Biome> biome, long inhabitedTime, @Nullable LevelChunkSection[] sectionArrayInitializer, @Nullable BlendingData blendingData) {
|
||||
super(pos, upgradeData, heightLimitView, biome, inhabitedTime, sectionArrayInitializer, blendingData);
|
||||
public LevelChunk_movableBEMixin(ChunkPos chunkPos, UpgradeData upgradeData, LevelHeightAccessor levelHeightAccessor, PalettedContainerFactory palettedContainerFactory, long l, @Nullable LevelChunkSection[] levelChunkSections, @Nullable BlendingData blendingData) {
|
||||
super(chunkPos, upgradeData, levelHeightAccessor, palettedContainerFactory, l, levelChunkSections, blendingData);
|
||||
}
|
||||
|
||||
@Shadow
|
||||
@@ -72,91 +75,122 @@ public abstract class LevelChunk_movableBEMixin extends ChunkAccess implements W
|
||||
*/
|
||||
/* @Nullable */
|
||||
// todo update me to the new version
|
||||
@Override
|
||||
public BlockState setBlockStateWithBlockEntity(BlockPos blockPos_1, BlockState newBlockState, BlockEntity newBlockEntity,
|
||||
boolean boolean_1)
|
||||
int flags)
|
||||
{
|
||||
int x = blockPos_1.getX() & 15;
|
||||
|
||||
int y = blockPos_1.getY();
|
||||
int z = blockPos_1.getZ() & 15;
|
||||
|
||||
LevelChunkSection chunkSection = this.getSection(this.getSectionIndex(y));
|
||||
if (chunkSection.hasOnlyAir())
|
||||
|
||||
boolean hadOnlyAir = chunkSection.hasOnlyAir();
|
||||
|
||||
if (hadOnlyAir && newBlockState.isAir())
|
||||
{
|
||||
if (newBlockState.isAir())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean boolean_2 = chunkSection.hasOnlyAir();
|
||||
BlockState oldBlockState = chunkSection.setBlockState(x, y & 15, z, newBlockState);
|
||||
|
||||
int x = blockPos_1.getX() & 15;
|
||||
int chunkY = blockPos_1.getY() & 15;
|
||||
int z = blockPos_1.getZ() & 15;
|
||||
BlockState oldBlockState = chunkSection.setBlockState(x, chunkY, z, newBlockState);
|
||||
if (oldBlockState == newBlockState)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
Block newBlock = newBlockState.getBlock();
|
||||
this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING).update(x, y, z, newBlockState);
|
||||
this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES).update(x, y, z, newBlockState);
|
||||
this.heightmaps.get(Heightmap.Types.OCEAN_FLOOR).update(x, y, z, newBlockState);
|
||||
this.heightmaps.get(Heightmap.Types.WORLD_SURFACE).update(x, y, z, newBlockState);
|
||||
boolean hasOnlyAir = chunkSection.hasOnlyAir();
|
||||
if (hadOnlyAir != hasOnlyAir)
|
||||
{
|
||||
Block newBlock = newBlockState.getBlock();
|
||||
Block oldBlock = oldBlockState.getBlock();
|
||||
((Heightmap) this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING)).update(x, y, z, newBlockState);
|
||||
((Heightmap) this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES)).update(x, y, z, newBlockState);
|
||||
((Heightmap) this.heightmaps.get(Heightmap.Types.OCEAN_FLOOR)).update(x, y, z, newBlockState);
|
||||
((Heightmap) this.heightmaps.get(Heightmap.Types.WORLD_SURFACE)).update(x, y, z, newBlockState);
|
||||
boolean boolean_3 = chunkSection.hasOnlyAir();
|
||||
if (boolean_2 != boolean_3)
|
||||
this.level.getChunkSource().getLightEngine().updateSectionStatus(blockPos_1, hasOnlyAir);
|
||||
this.level.getChunkSource().onSectionEmptinessChanged(chunkPos.x(), SectionPos.blockToSectionCoord(y), chunkPos.z(), hasOnlyAir);
|
||||
}
|
||||
|
||||
if (LightEngine.hasDifferentLightProperties(oldBlockState, newBlockState)) {
|
||||
ProfilerFiller profiler = Profiler.get();
|
||||
profiler.push("updateSkyLightSources");
|
||||
if (skyLightSources != null) // compat with ScalableLux aka Starlight port
|
||||
{
|
||||
this.level.getChunkSource().getLightEngine().updateSectionStatus(blockPos_1, boolean_3);
|
||||
skyLightSources.update(this, x, chunkY, z);
|
||||
}
|
||||
|
||||
if (!this.level.isClientSide)
|
||||
{
|
||||
if (!(oldBlock instanceof MovingPistonBlock))//this is a movableTE special case, if condition wasn't there it would remove the blockentity that was carried for some reason
|
||||
oldBlockState.onRemove(this.level, blockPos_1, newBlockState, boolean_1);//this kills it
|
||||
profiler.popPush("queueCheckLight");
|
||||
level.getChunkSource().getLightEngine().checkBlock(blockPos_1);
|
||||
profiler.pop();
|
||||
}
|
||||
|
||||
boolean blockChanged = !oldBlockState.is(newBlock);
|
||||
boolean movedByPiston = (flags & Block.UPDATE_MOVE_BY_PISTON) != 0; // moved by pistons
|
||||
boolean sideEffects = (flags & Block.UPDATE_SKIP_BLOCK_ENTITY_SIDEEFFECTS) == 0;
|
||||
|
||||
if (blockChanged && oldBlockState.hasBlockEntity()) {
|
||||
if (level instanceof ServerLevel && !(oldBlockState.getBlock() instanceof MovingPistonBlock)) {
|
||||
if (sideEffects) {
|
||||
BlockEntity blockEntity = level.getBlockEntity(blockPos_1);
|
||||
if (blockEntity != null) {
|
||||
blockEntity.preRemoveSideEffects(blockPos_1, oldBlockState);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (oldBlock != newBlock && oldBlock instanceof EntityBlock)
|
||||
removeBlockEntity(blockPos_1);
|
||||
}
|
||||
|
||||
if (blockChanged || newBlock instanceof BaseRailBlock)
|
||||
{
|
||||
if (level instanceof ServerLevel serverLevel && !(oldBlockState.getBlock() instanceof MovingPistonBlock))
|
||||
{
|
||||
this.level.removeBlockEntity(blockPos_1);
|
||||
if ((flags & Block.UPDATE_NEIGHBORS) != 0 || movedByPiston)
|
||||
{
|
||||
oldBlockState.affectNeighborsAfterRemoval(serverLevel, blockPos_1, movedByPiston);
|
||||
}
|
||||
}
|
||||
|
||||
if (chunkSection.getBlockState(x, y & 15, z).getBlock() != newBlock)
|
||||
}
|
||||
|
||||
|
||||
if (chunkSection.getBlockState(x, chunkY, z).getBlock() != newBlock)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!level.isClientSide() && sideEffects) {
|
||||
// this updates stuff, schedule ticks - do we want that since its only be called from MovingPistonBlock really?
|
||||
newBlockState.onPlace(level, blockPos_1, oldBlockState, movedByPiston);
|
||||
}
|
||||
|
||||
BlockEntity oldBlockEntity = null;
|
||||
if (oldBlockState.hasBlockEntity())
|
||||
{
|
||||
oldBlockEntity = this.getBlockEntity(blockPos_1, LevelChunk.EntityCreationType.CHECK);
|
||||
if (oldBlockEntity != null && !oldBlockEntity.isValidBlockState(oldBlockState))
|
||||
{
|
||||
return null;
|
||||
oldBlockEntity.setBlockState(oldBlockState);
|
||||
updateBlockEntityTicker(oldBlockEntity);
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockEntity oldBlockEntity = null;
|
||||
if (oldBlockState.hasBlockEntity())
|
||||
if (newBlockEntity == null)
|
||||
{
|
||||
oldBlockEntity = this.getBlockEntity(blockPos_1, LevelChunk.EntityCreationType.CHECK);
|
||||
if (oldBlockEntity != null)
|
||||
newBlockEntity = ((EntityBlock) newBlock).newBlockEntity(blockPos_1, newBlockState);
|
||||
if (newBlockEntity != null)
|
||||
{
|
||||
oldBlockEntity.setBlockState(oldBlockState);
|
||||
updateBlockEntityTicker(oldBlockEntity);
|
||||
addAndRegisterBlockEntity(newBlockEntity);
|
||||
}
|
||||
}
|
||||
|
||||
if (oldBlockState.hasBlockEntity())
|
||||
if (newBlockEntity != oldBlockEntity && newBlockEntity != null)
|
||||
{
|
||||
if (newBlockEntity == null)
|
||||
{
|
||||
newBlockEntity = ((EntityBlock) newBlock).newBlockEntity(blockPos_1, newBlockState);
|
||||
}
|
||||
if (newBlockEntity != oldBlockEntity && newBlockEntity != null)
|
||||
{
|
||||
newBlockEntity.clearRemoved();
|
||||
this.level.setBlockEntity(newBlockEntity);
|
||||
newBlockEntity.setBlockState(newBlockState);
|
||||
updateBlockEntityTicker(newBlockEntity);
|
||||
}
|
||||
newBlockEntity.clearRemoved();
|
||||
this.level.setBlockEntity(newBlockEntity);
|
||||
newBlockEntity.setBlockState(newBlockState);
|
||||
updateBlockEntityTicker(newBlockEntity);
|
||||
}
|
||||
|
||||
if (!this.level.isClientSide)
|
||||
{
|
||||
newBlockState.onPlace(this.level, blockPos_1, oldBlockState, boolean_1); //This can call setblockstate! (e.g. hopper does)
|
||||
}
|
||||
|
||||
this.unsaved = true; // shouldSave
|
||||
return oldBlockState;
|
||||
}
|
||||
}
|
||||
|
||||
markUnsaved();
|
||||
return oldBlockState;
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ public class LevelEntityGetterAdapter_scarpetMixin<T extends EntityAccess> imple
|
||||
|
||||
@Override
|
||||
public List<T> getChunkEntities(ChunkPos chpos) {
|
||||
return this.sectionStorage.getExistingSectionsInChunk(chpos.toLong()).flatMap(EntitySection::getEntities).collect(Collectors.toList());
|
||||
return this.sectionStorage.getExistingSectionsInChunk(chpos.pack()).flatMap(EntitySection::getEntities).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(LevelRenderer.class)
|
||||
@Mixin(Camera.class)
|
||||
public class LevelRenderer_creativeNoClipMixin
|
||||
{
|
||||
@Redirect(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;isSpectator()Z"))
|
||||
@Redirect(method = "extractRenderState", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;isSpectator()Z"))
|
||||
private boolean canSeeWorld(LocalPlayer clientPlayerEntity)
|
||||
{
|
||||
return clientPlayerEntity.isSpectator() || (CarpetSettings.creativeNoClip && clientPlayerEntity.isCreative());
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.client.renderer.DimensionSpecialEffects;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
//import net.minecraft.world.dimension.Dimension;
|
||||
import net.minecraft.client.renderer.fog.environment.AtmosphericFogEnvironment;
|
||||
import net.minecraft.world.attribute.EnvironmentAttribute;
|
||||
import net.minecraft.world.attribute.EnvironmentAttributeProbe;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(value = LevelRenderer.class, priority = 69420)
|
||||
@Mixin(value = AtmosphericFogEnvironment.class, priority = 69420)
|
||||
public class LevelRenderer_fogOffMixin
|
||||
{
|
||||
@Redirect(method = "renderLevel", require = 0, expect = 0, at = @At(
|
||||
@Redirect(method = "setupFog", require = 0, expect = 0, at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/renderer/DimensionSpecialEffects;isFoggyAt(II)Z"
|
||||
target = "Lnet/minecraft/world/attribute/EnvironmentAttributeProbe;getValue(Lnet/minecraft/world/attribute/EnvironmentAttribute;F)Ljava/lang/Object;"
|
||||
))
|
||||
private boolean isReallyThick(DimensionSpecialEffects skyProperties, int x, int z)
|
||||
private <Value> Value isReallyThick(EnvironmentAttributeProbe instance, EnvironmentAttribute<Value> environmentAttribute, float f)
|
||||
{
|
||||
if (CarpetSettings.fogOff) return false;
|
||||
return skyProperties.isFoggyAt(x, z);
|
||||
if (CarpetSettings.fogOff) return environmentAttribute.defaultValue();
|
||||
return instance.getValue(environmentAttribute, f);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,18 +2,35 @@ package carpet.mixins;
|
||||
|
||||
import carpet.network.CarpetClient;
|
||||
import carpet.script.utils.ShapesRenderer;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Camera;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.framegraph.FrameGraphBuilder;
|
||||
import com.mojang.blaze3d.framegraph.FramePass;
|
||||
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
|
||||
import net.minecraft.client.DeltaTracker;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.LevelTargetBundle;
|
||||
import net.minecraft.client.renderer.RenderBuffers;
|
||||
import net.minecraft.client.renderer.ShaderManager;
|
||||
import net.minecraft.client.renderer.SubmitNodeCollector;
|
||||
import net.minecraft.client.renderer.SubmitNodeStorage;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
|
||||
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
|
||||
import org.joml.Matrix4f;
|
||||
import net.minecraft.client.renderer.feature.FeatureRenderDispatcher;
|
||||
import net.minecraft.client.renderer.state.GameRenderState;
|
||||
import net.minecraft.client.renderer.state.level.CameraRenderState;
|
||||
import net.minecraft.client.renderer.state.level.LevelRenderState;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.client.resources.model.sprite.AtlasManager;
|
||||
import org.joml.Matrix4fc;
|
||||
import org.joml.Vector4f;
|
||||
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;
|
||||
@@ -21,30 +38,45 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@Mixin(LevelRenderer.class)
|
||||
public class LevelRenderer_scarpetRenderMixin
|
||||
{
|
||||
@Shadow @Final private LevelTargetBundle targets;
|
||||
|
||||
@Shadow @Final private FeatureRenderDispatcher featureRenderDispatcher;
|
||||
|
||||
@Shadow @Final private RenderBuffers renderBuffers;
|
||||
|
||||
@Shadow @Final private LevelRenderState levelRenderState;
|
||||
|
||||
@Shadow @Final private SubmitNodeStorage submitNodeStorage;
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void addRenderers(Minecraft minecraft, EntityRenderDispatcher entityRenderDispatcher, BlockEntityRenderDispatcher blockEntityRenderDispatcher, RenderBuffers renderBuffers, CallbackInfo ci)
|
||||
private void addRenderers(EntityRenderDispatcher entityRenderDispatcher, BlockEntityRenderDispatcher blockEntityRenderDispatcher, ModelManager modelManager, TextureManager textureManager, AtlasManager atlasManager, ShaderManager shaderManager, GameRenderer gameRenderer, int width, int height, CallbackInfo ci)
|
||||
{
|
||||
CarpetClient.shapes = new ShapesRenderer(minecraft);
|
||||
CarpetClient.shapes = new ShapesRenderer(Minecraft.getInstance());
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(
|
||||
@Inject(method = "render", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/renderer/Sheets;translucentCullBlockSheet()Lnet/minecraft/client/renderer/RenderType;", shift = At.Shift.BEFORE
|
||||
//target = "Lnet/minecraft/client/render/RenderLayer;getWaterMask()Lnet/minecraft/client/render/RenderLayer;", shift = At.Shift.AFTER
|
||||
//target = "Lnet/minecraft/client/render/BufferBuilderStorage;getEffectVertexConsumers()Lnet/minecraft/client/render/VertexConsumerProvider$Immediate;", shift = At.Shift.BEFORE
|
||||
//target = "Lnet/minecraft/client/render/WorldRenderer;renderChunkDebugInfo(Lnet/minecraft/client/render/Camera;)V", shift = At.Shift.AFTER
|
||||
//target = "Lnet/minecraft/client/render/BackgroundRenderer;method_23792()V", shift = At.Shift.AFTER
|
||||
//target = "Lnet/minecraft/client/render/BufferBuilderStorage;getEntityVertexConsumers()Lnet/minecraft/client/render/VertexConsumerProvider$Immediate;", shift = At.Shift.AFTER
|
||||
//target = "Lnet/minecraft/client/render/WorldRenderer;renderChunkDebugInfo(Lnet/minecraft/client/render/Camera;)V", shift = At.Shift.AFTER // before return
|
||||
target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/feature/FeatureRenderDispatcher$PreparedFrame;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/util/profiling/ProfilerFiller;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V",
|
||||
//target = "Lnet/minecraft/client/renderer/LevelRenderer;addAlwaysOnTopPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;)V",
|
||||
//target = "Lnet/minecraft/client/renderer/LevelRenderer;submitFeatures(Lnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/client/renderer/SubmitNodeCollector;Z)V",
|
||||
//target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/util/profiling/ProfilerFiller;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V",
|
||||
//target = "Lnet/minecraft/client/renderer/LevelRenderer;addLateDebugPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/state/level/CameraRenderState;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lorg/joml/Matrix4fc;)V",
|
||||
shift = At.Shift.AFTER
|
||||
))
|
||||
private void renderScarpetThings(final DeltaTracker deltaTracker, final boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightmapTextureManager, Matrix4f modelViewMatrix, Matrix4f matrix4f, CallbackInfo ci)
|
||||
private void renderScarpetThingsLate(GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker, boolean renderOutline, CameraRenderState cameraState, Matrix4fc modelViewMatrix, GpuBufferSlice terrainFog, Vector4f fogColor, boolean shouldRenderSky, CallbackInfo ci, @Local FrameGraphBuilder frameGraphBuilder)
|
||||
//private void renderScarpetThinsLate(GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker, boolean renderOutline, CameraRenderState cameraState, Matrix4fc modelViewMatrix, GpuBufferSlice terrainFog, Vector4f fogColor, boolean shouldRenderSky, CallbackInfo ci, @Local FrameGraphBuilder frameGraphBuilder)
|
||||
{
|
||||
// in normal circumstances we want to render shapes at the very end so it appears correctly behind stuff.
|
||||
// we might actually not need to play with render hooks here.
|
||||
//if (!FabricAPIHooks.WORLD_RENDER_EVENTS && CarpetClient.shapes != null )
|
||||
if (CarpetClient.shapes != null)
|
||||
{
|
||||
CarpetClient.shapes.render(modelViewMatrix, camera, deltaTracker.getGameTimeDeltaPartialTick(false));
|
||||
final float deltaPartialTick = deltaTracker.getGameTimeDeltaPartialTick(false);
|
||||
FramePass pass = frameGraphBuilder.addPass("scarpet_shapes");
|
||||
targets.main = pass.readsAndWrites(targets.main);
|
||||
pass.executes(() -> CarpetClient.shapes.render(submitNodeStorage, levelRenderState, modelViewMatrix, deltaPartialTick));
|
||||
//featureRenderDispatcher.renderAllFeatures(submitNodeStorage);
|
||||
//renderBuffers.bufferSource().uploadAndDraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,11 +23,11 @@ public abstract class Level_fillUpdatesMixin
|
||||
|
||||
@Redirect(method = "setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;II)Z", at = @At( //setBlockState main
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/Level;blockUpdated(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;)V"
|
||||
target = "Lnet/minecraft/world/level/Level;updateNeighborsAt(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;)V"
|
||||
))
|
||||
private void updateNeighborsMaybe(Level world, BlockPos blockPos, Block block)
|
||||
{
|
||||
if (!CarpetSettings.impendingFillSkipUpdates.get()) world.blockUpdated(blockPos, block);
|
||||
if (!CarpetSettings.impendingFillSkipUpdates.get()) world.updateNeighborsAt(blockPos, block);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package carpet.mixins;
|
||||
|
||||
import carpet.fakes.LevelInterface;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.minecraft.util.profiling.Profiler;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@@ -9,9 +10,8 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Predicate;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.boss.EnderDragonPart;
|
||||
import net.minecraft.world.entity.boss.enderdragon.EnderDragonPart;
|
||||
import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.entity.LevelEntityGetter;
|
||||
@@ -24,7 +24,7 @@ public abstract class Level_getOtherEntitiesLimited implements LevelInterface {
|
||||
|
||||
@Override
|
||||
public List<Entity> getOtherEntitiesLimited(@Nullable Entity except, AABB box, Predicate<? super Entity> predicate, int limit) {
|
||||
this.getProfiler().incrementCounter("getEntities"); // visit
|
||||
Profiler.get().incrementCounter("getEntities"); // visit
|
||||
AtomicInteger checkedEntities = new AtomicInteger();
|
||||
List<Entity> list = Lists.newArrayList();
|
||||
try {
|
||||
@@ -55,9 +55,6 @@ public abstract class Level_getOtherEntitiesLimited implements LevelInterface {
|
||||
return list;
|
||||
}
|
||||
|
||||
@Shadow
|
||||
public abstract ProfilerFiller getProfiler();
|
||||
|
||||
@Shadow
|
||||
protected abstract LevelEntityGetter<Entity> getEntities();
|
||||
}
|
||||
@@ -4,8 +4,8 @@ import carpet.fakes.WorldChunkInterface;
|
||||
import carpet.fakes.LevelInterface;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.FullChunkStatus;
|
||||
import net.minecraft.util.profiling.Profiler;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
@@ -28,32 +28,18 @@ public abstract class Level_movableBEMixin implements LevelInterface, LevelAcces
|
||||
@Shadow
|
||||
public abstract LevelChunk getChunkAt(BlockPos blockPos_1);
|
||||
|
||||
@Shadow
|
||||
public abstract BlockState getBlockState(BlockPos blockPos_1);
|
||||
|
||||
//@Shadow
|
||||
//public abstract ChunkManager getChunkManager();
|
||||
|
||||
@Shadow
|
||||
public abstract void setBlocksDirty(BlockPos blockPos_1, BlockState s1, BlockState s2);
|
||||
|
||||
@Shadow
|
||||
public abstract void sendBlockUpdated(BlockPos var1, BlockState var2, BlockState var3, int var4);
|
||||
|
||||
@Shadow
|
||||
public abstract void updateNeighborsAt(BlockPos blockPos_1, Block block_1);
|
||||
|
||||
@Shadow
|
||||
public abstract void onBlockStateChange(BlockPos blockPos_1, BlockState blockState_1, BlockState blockState_2);
|
||||
|
||||
@Shadow public abstract ProfilerFiller getProfiler();
|
||||
|
||||
@Shadow public abstract void updateNeighbourForOutputSignal(BlockPos pos, Block block);
|
||||
|
||||
//@Shadow public abstract boolean setBlockState(BlockPos pos, BlockState state, int flags);
|
||||
|
||||
@Shadow public abstract boolean isDebug();
|
||||
|
||||
@Shadow public abstract void updatePOIOnBlockStateChange(final BlockPos blockPos, final BlockState blockState, final BlockState blockState2);
|
||||
|
||||
/**
|
||||
* @author 2No2Name
|
||||
*/
|
||||
@@ -67,7 +53,7 @@ public abstract class Level_movableBEMixin implements LevelInterface, LevelAcces
|
||||
BlockState blockState_2;
|
||||
if (newBlockEntity != null && block_1 instanceof EntityBlock)
|
||||
{
|
||||
blockState_2 = ((WorldChunkInterface) worldChunk_1).setBlockStateWithBlockEntity(blockPos_1, blockState_1, newBlockEntity, (int_1 & 64) != 0);
|
||||
blockState_2 = ((WorldChunkInterface) worldChunk_1).setBlockStateWithBlockEntity(blockPos_1, blockState_1, newBlockEntity, int_1);
|
||||
if (newBlockEntity instanceof LidBlockEntity)
|
||||
{
|
||||
scheduleTick(blockPos_1, block_1, 5);
|
||||
@@ -75,56 +61,46 @@ public abstract class Level_movableBEMixin implements LevelInterface, LevelAcces
|
||||
}
|
||||
else
|
||||
{
|
||||
blockState_2 = worldChunk_1.setBlockState(blockPos_1, blockState_1, (int_1 & 64) != 0);
|
||||
blockState_2 = worldChunk_1.setBlockState(blockPos_1, blockState_1, int_1);
|
||||
}
|
||||
|
||||
if (blockState_2 == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
||||
BlockState blockState_3 = this.getBlockState(blockPos_1);
|
||||
|
||||
if (blockState_3 == blockState_1)
|
||||
{
|
||||
BlockState blockState_3 = this.getBlockState(blockPos_1);
|
||||
|
||||
if (blockState_3 != blockState_2 && (blockState_3.getLightBlock((BlockGetter) this, blockPos_1) != blockState_2.getLightBlock((BlockGetter) this, blockPos_1) || blockState_3.getLightEmission() != blockState_2.getLightEmission() || blockState_3.useShapeForLightOcclusion() || blockState_2.useShapeForLightOcclusion()))
|
||||
if (blockState_2 != blockState_3)
|
||||
{
|
||||
ProfilerFiller profiler = getProfiler();
|
||||
profiler.push("queueCheckLight");
|
||||
this.getChunkSource().getLightEngine().checkBlock(blockPos_1);
|
||||
profiler.pop();
|
||||
this.setBlocksDirty(blockPos_1, blockState_2, blockState_3);
|
||||
}
|
||||
|
||||
if (blockState_3 == blockState_1)
|
||||
if ((int_1 & 2) != 0 && (!this.isClientSide || (int_1 & 4) == 0) && (this.isClientSide || worldChunk_1.getFullStatus() != null && worldChunk_1.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING)))
|
||||
{
|
||||
if (blockState_2 != blockState_3)
|
||||
{
|
||||
this.setBlocksDirty(blockPos_1, blockState_2, blockState_3);
|
||||
}
|
||||
|
||||
if ((int_1 & 2) != 0 && (!this.isClientSide || (int_1 & 4) == 0) && (this.isClientSide || worldChunk_1.getFullStatus() != null && worldChunk_1.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING)))
|
||||
{
|
||||
this.sendBlockUpdated(blockPos_1, blockState_2, blockState_1, int_1);
|
||||
}
|
||||
|
||||
if (!this.isClientSide && (int_1 & 1) != 0)
|
||||
{
|
||||
this.updateNeighborsAt(blockPos_1, blockState_2.getBlock());
|
||||
if (blockState_1.hasAnalogOutputSignal())
|
||||
{
|
||||
updateNeighbourForOutputSignal(blockPos_1, block_1);
|
||||
}
|
||||
}
|
||||
|
||||
if ((int_1 & 16) == 0)
|
||||
{
|
||||
int int_2 = int_1 & -34;
|
||||
blockState_2.updateIndirectNeighbourShapes(this, blockPos_1, int_2); // prepare
|
||||
blockState_1.updateNeighbourShapes(this, blockPos_1, int_2); // updateNeighbours
|
||||
blockState_1.updateIndirectNeighbourShapes(this, blockPos_1, int_2); // prepare
|
||||
}
|
||||
this.onBlockStateChange(blockPos_1, blockState_2, blockState_3);
|
||||
this.sendBlockUpdated(blockPos_1, blockState_2, blockState_1, int_1);
|
||||
}
|
||||
return true;
|
||||
|
||||
if (!this.isClientSide && (int_1 & 1) != 0)
|
||||
{
|
||||
this.updateNeighborsAt(blockPos_1, blockState_2.getBlock());
|
||||
if (blockState_1.hasAnalogOutputSignal())
|
||||
{
|
||||
updateNeighbourForOutputSignal(blockPos_1, block_1);
|
||||
}
|
||||
}
|
||||
|
||||
if ((int_1 & 16) == 0)
|
||||
{
|
||||
int int_2 = int_1 & -34;
|
||||
blockState_2.updateIndirectNeighbourShapes(this, blockPos_1, int_2); // prepare
|
||||
blockState_1.updateNeighbourShapes(this, blockPos_1, int_2); // updateNeighbours
|
||||
blockState_1.updateIndirectNeighbourShapes(this, blockPos_1, int_2); // prepare
|
||||
}
|
||||
updatePOIOnBlockStateChange(blockPos_1, blockState_2, blockState_3);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package carpet.mixins;
|
||||
|
||||
import carpet.fakes.LevelInterface;
|
||||
import carpet.utils.CarpetProfiler;
|
||||
import net.minecraft.world.level.redstone.NeighborUpdater;
|
||||
import net.minecraft.world.level.redstone.CollectingNeighborUpdater;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@@ -22,7 +22,7 @@ import net.minecraft.world.level.Level;
|
||||
public abstract class Level_tickMixin implements LevelInterface
|
||||
{
|
||||
@Shadow @Final public boolean isClientSide;
|
||||
@Shadow @Final protected NeighborUpdater neighborUpdater;
|
||||
@Shadow @Final protected CollectingNeighborUpdater neighborUpdater;
|
||||
CarpetProfiler.ProfilerToken currentSection;
|
||||
CarpetProfiler.ProfilerToken entitySection;
|
||||
|
||||
@@ -30,7 +30,7 @@ public abstract class Level_tickMixin implements LevelInterface
|
||||
|
||||
@Override
|
||||
@Unique
|
||||
public NeighborUpdater getNeighborUpdater() {
|
||||
public CollectingNeighborUpdater getNeighborUpdater() {
|
||||
return this.neighborUpdater;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.gamerules.GameRules;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
@@ -22,6 +23,6 @@ public abstract class LivingEntity_cleanLogsMixin extends Entity
|
||||
@Redirect(method = "die", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;hasCustomName()Z"))
|
||||
private boolean shouldLogDeaths(LivingEntity livingEntity)
|
||||
{
|
||||
return livingEntity.hasCustomName() && CarpetSettings.cleanLogs && level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES);
|
||||
return livingEntity.hasCustomName() && livingEntity.level() instanceof ServerLevel serverLevel && CarpetSettings.cleanLogs && serverLevel.getGameRules().get(GameRules.SHOW_DEATH_MESSAGES);
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,8 @@ public abstract class LivingEntity_creativeFlyMixin extends Entity
|
||||
super(type, world);
|
||||
}
|
||||
|
||||
@ModifyConstant(method = "travel", constant = @Constant(floatValue = 0.91F), expect = 2)
|
||||
private float drag(float original)
|
||||
@ModifyConstant(method = "travelInAir", constant = @Constant(floatValue = 0.91F), expect = 1)
|
||||
private float dragAir(float original)
|
||||
{
|
||||
if (CarpetSettings.creativeFlyDrag != 0.09 && (Object)this instanceof Player)
|
||||
{
|
||||
@@ -37,7 +37,6 @@ public abstract class LivingEntity_creativeFlyMixin extends Entity
|
||||
return original;
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "getFrictionInfluencedSpeed(F)F", at = @At("HEAD"), cancellable = true)
|
||||
private void flyingAltSpeed(float slipperiness, CallbackInfoReturnable<Float> cir)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,8 @@ package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.fakes.LevelInterface;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.gamerules.GameRules;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
@@ -13,7 +15,6 @@ import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntitySelector;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
@Mixin(LivingEntity.class)
|
||||
@@ -33,12 +34,18 @@ public abstract class LivingEntity_maxCollisionsMixin extends Entity
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(this.level() instanceof ServerLevel serverLevel))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<Entity> entities;
|
||||
int maxEntityCramming =-1;
|
||||
if (CarpetSettings.maxEntityCollisions > 0)
|
||||
{
|
||||
maxEntityCramming = this.level().getGameRules().getInt(GameRules.RULE_MAX_ENTITY_CRAMMING);
|
||||
entities = ((LevelInterface) this.level()).getOtherEntitiesLimited(
|
||||
maxEntityCramming = serverLevel.getGameRules().get(GameRules.MAX_ENTITY_CRAMMING);
|
||||
entities = ((LevelInterface) serverLevel).getOtherEntitiesLimited(
|
||||
this,
|
||||
this.getBoundingBox(),
|
||||
EntitySelector.pushableBy(this),
|
||||
@@ -46,11 +53,11 @@ public abstract class LivingEntity_maxCollisionsMixin extends Entity
|
||||
}
|
||||
else
|
||||
{
|
||||
entities = this.level().getEntities(this, this.getBoundingBox(), EntitySelector.pushableBy(this));
|
||||
entities = serverLevel.getEntities(this, this.getBoundingBox(), EntitySelector.pushableBy(this));
|
||||
}
|
||||
|
||||
if (!entities.isEmpty()) {
|
||||
if (maxEntityCramming < 0) maxEntityCramming = this.level().getGameRules().getInt(GameRules.RULE_MAX_ENTITY_CRAMMING);
|
||||
if (maxEntityCramming < 0) maxEntityCramming = serverLevel.getGameRules().get(GameRules.MAX_ENTITY_CRAMMING);
|
||||
if (maxEntityCramming > 0 && entities.size() > maxEntityCramming - 1 && this.random.nextInt(4) == 0) {
|
||||
int candidates = 0;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package carpet.mixins;
|
||||
import carpet.fakes.EntityInterface;
|
||||
import carpet.fakes.LivingEntityInterface;
|
||||
import carpet.script.EntityEventsGroup;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
@@ -42,7 +43,7 @@ public abstract class LivingEntity_scarpetEventsMixin extends Entity implements
|
||||
target = "Lnet/minecraft/world/entity/LivingEntity;getDamageAfterArmorAbsorb(Lnet/minecraft/world/damagesource/DamageSource;F)F",
|
||||
shift = At.Shift.BEFORE
|
||||
))
|
||||
private void entityTakingDamage(DamageSource source, float amount, CallbackInfo ci)
|
||||
private void entityTakingDamage(ServerLevel serverLevel, DamageSource source, float amount, CallbackInfo ci)
|
||||
{
|
||||
((EntityInterface)this).getEventContainer().onEvent(EntityEventsGroup.Event.ON_DAMAGE, amount, source);
|
||||
// this is not applicable since its not a playr for sure
|
||||
|
||||
@@ -15,8 +15,8 @@ public class MinecraftMixin
|
||||
{
|
||||
@Shadow public ClientLevel level;
|
||||
|
||||
@Inject(method = "disconnect(Lnet/minecraft/client/gui/screens/Screen;)V", at = @At("HEAD"))
|
||||
private void onCloseGame(Screen screen, CallbackInfo ci)
|
||||
@Inject(method = "disconnect(Lnet/minecraft/client/gui/screens/Screen;Z)V", at = @At("HEAD"))
|
||||
private void onCloseGame(Screen screen, boolean b, CallbackInfo ci)
|
||||
{
|
||||
CarpetClient.disconnect();
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import net.minecraft.server.MinecraftServer;
|
||||
public abstract class MinecraftServer_pingPlayerSampleLimit
|
||||
{
|
||||
|
||||
@ModifyConstant(method = "tickServer", constant = @Constant(intValue = 12), require = 0, allow = 1)
|
||||
@ModifyConstant(method = "buildPlayerStatus", constant = @Constant(intValue = 12), require = 1)
|
||||
private int modifyPlayerSampleLimit(int value)
|
||||
{
|
||||
return CarpetSettings.pingPlayerListLimit;
|
||||
|
||||
@@ -2,7 +2,7 @@ package carpet.mixins;
|
||||
|
||||
import carpet.fakes.MinecraftServerInterface;
|
||||
import carpet.script.CarpetScriptServer;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
@@ -34,9 +34,8 @@ public abstract class MinecraftServer_scarpetMixin extends ReentrantBlockableEve
|
||||
{
|
||||
private CarpetScriptServer scriptServer;
|
||||
|
||||
public MinecraftServer_scarpetMixin(String string_1)
|
||||
{
|
||||
super(string_1);
|
||||
public MinecraftServer_scarpetMixin(String name, boolean propagatesCrashes) {
|
||||
super(name, propagatesCrashes);
|
||||
}
|
||||
|
||||
@Shadow protected abstract void tickServer(BooleanSupplier booleanSupplier_1);
|
||||
@@ -102,7 +101,7 @@ public abstract class MinecraftServer_scarpetMixin extends ReentrantBlockableEve
|
||||
@Override
|
||||
public void reloadAfterReload(RegistryAccess newRegs)
|
||||
{
|
||||
resources.managers().updateRegistryTags();
|
||||
resources.managers().updateComponentsAndStaticRegistryTags();
|
||||
getPlayerList().saveAll();
|
||||
getPlayerList().reloadResources();
|
||||
functionManager.replaceLibrary(this.resources.managers().getFunctionLibrary());
|
||||
|
||||
@@ -10,23 +10,22 @@ 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.function.BooleanSupplier;
|
||||
|
||||
@Mixin(value = MinecraftServer.class, priority = Integer.MAX_VALUE - 10)
|
||||
public abstract class MinecraftServer_tickspeedMixin extends ReentrantBlockableEventLoop<TickTask> implements MinecraftServerInterface
|
||||
{
|
||||
public MinecraftServer_tickspeedMixin(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
|
||||
|
||||
CarpetProfiler.ProfilerToken currentSection;
|
||||
|
||||
public MinecraftServer_tickspeedMixin(String name, boolean propagatesCrashes) {
|
||||
super(name, propagatesCrashes);
|
||||
}
|
||||
|
||||
// Replaced the above cancelled while statement with this one
|
||||
// could possibly just inject that mspt selection at the beginning of the loop, but then adding all mspt's to
|
||||
// replace 50L will be a hassle
|
||||
@Inject(method = "runServer", at = @At(value = "INVOKE", shift = At.Shift.AFTER,
|
||||
target = "Lnet/minecraft/server/MinecraftServer;startMetricsRecordingTick()V"))
|
||||
target = "Lnet/minecraft/util/profiling/Profiler;get()Lnet/minecraft/util/profiling/ProfilerFiller;"))
|
||||
private void modifiedRunLoop(CallbackInfo ci)
|
||||
{
|
||||
if (CarpetProfiler.tick_health_requested != 0L)
|
||||
@@ -36,42 +35,34 @@ public abstract class MinecraftServer_tickspeedMixin extends ReentrantBlockableE
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "tickServer", at = @At(
|
||||
@Inject(method = "autoSave", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/server/MinecraftServer;saveEverything(ZZZ)Z", // save
|
||||
shift = At.Shift.BEFORE
|
||||
))
|
||||
private void startAutosave(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
||||
private void startAutosave(final CallbackInfo ci)
|
||||
{
|
||||
currentSection = CarpetProfiler.start_section(null, "Autosave", CarpetProfiler.TYPE.GENERAL);
|
||||
}
|
||||
|
||||
@Inject(method = "tickServer", at = @At(
|
||||
@Inject(method = "autoSave", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/server/MinecraftServer;saveEverything(ZZZ)Z",
|
||||
shift = At.Shift.AFTER
|
||||
))
|
||||
private void finishAutosave(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
||||
private void finishAutosave(final CallbackInfo ci)
|
||||
{
|
||||
CarpetProfiler.end_current_section(currentSection);
|
||||
}
|
||||
|
||||
@Inject(method = "tickChildren", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/server/MinecraftServer;getConnection()Lnet/minecraft/server/network/ServerConnectionListener;",
|
||||
shift = At.Shift.BEFORE
|
||||
))
|
||||
private void startNetwork(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
||||
@Inject(method = "tickConnection", at = @At("HEAD"))
|
||||
private void startNetwork(final CallbackInfo ci)
|
||||
{
|
||||
currentSection = CarpetProfiler.start_section(null, "Network", CarpetProfiler.TYPE.GENERAL);
|
||||
}
|
||||
|
||||
@Inject(method = "tickChildren", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/server/players/PlayerList;tick()V",
|
||||
shift = At.Shift.AFTER
|
||||
))
|
||||
private void finishNetwork(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
||||
@Inject(method = "tickConnection", at = @At("RETURN"))
|
||||
private void finishNetwork(final CallbackInfo ci)
|
||||
{
|
||||
CarpetProfiler.end_current_section(currentSection);
|
||||
}
|
||||
@@ -94,6 +85,4 @@ public abstract class MinecraftServer_tickspeedMixin extends ReentrantBlockableE
|
||||
CarpetProfiler.end_tick_profiling((MinecraftServer) (Object)this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.utils.SpawnOverrides;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.EntityTypes;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.monster.Monster;
|
||||
import net.minecraft.world.level.ServerLevelAccessor;
|
||||
import net.minecraft.world.level.levelgen.structure.BuiltinStructures;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(Monster.class)
|
||||
public class Monster_templesMixin
|
||||
{
|
||||
@Redirect(method = "checkSurfaceMonstersSpawnRules", at = @At(value = "INVOKE", target="Lnet/minecraft/world/level/ServerLevelAccessor;canSeeSky(Lnet/minecraft/core/BlockPos;)Z"))
|
||||
private static boolean isSkylightOrTempleVisible(ServerLevelAccessor serverWorldAccess, BlockPos pos,
|
||||
EntityType<? extends Mob> entityType, ServerLevelAccessor serverLevelAccessor, EntitySpawnReason entitySpawnReason, BlockPos blockPos, RandomSource randomSource)
|
||||
{
|
||||
return serverWorldAccess.canSeeSky(pos) ||
|
||||
(CarpetSettings.huskSpawningInTemples && entityType == EntityTypes.HUSK && SpawnOverrides.isStructureAtPosition((ServerLevel)serverWorldAccess, BuiltinStructures.DESERT_PYRAMID, pos));
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,9 @@ package carpet.mixins;
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.fakes.LevelInterface;
|
||||
import carpet.utils.SpawnReporter;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -12,9 +15,9 @@ 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.List;
|
||||
import java.util.Map;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
@@ -24,7 +27,6 @@ import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.MobCategory;
|
||||
import net.minecraft.world.entity.MobSpawnType;
|
||||
import net.minecraft.world.entity.SpawnGroupData;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
@@ -46,12 +48,12 @@ public class NaturalSpawnerMixin
|
||||
|
||||
@Shadow @Final private static MobCategory[] SPAWNING_CATEGORIES;
|
||||
|
||||
@Redirect(method = "isValidSpawnPostitionForType",
|
||||
at = @At(
|
||||
@WrapOperation(method = "isValidSpawnPostitionForType",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/server/level/ServerLevel;noCollision(Lnet/minecraft/world/phys/AABB;)Z"
|
||||
))
|
||||
private static boolean doesNotCollide(ServerLevel world, AABB bb)
|
||||
private static boolean doesNotCollide(ServerLevel world, AABB bb, Operation<Boolean> original)
|
||||
{
|
||||
//.doesNotCollide is VERY expensive. On the other side - most worlds are not made of trapdoors in
|
||||
// various configurations, but solid and 'passable' blocks, like air, water grass, etc.
|
||||
@@ -59,7 +61,7 @@ public class NaturalSpawnerMixin
|
||||
// in case something more complex happens - we default to full block collision check
|
||||
if (!CarpetSettings.lagFreeSpawning)
|
||||
{
|
||||
return world.noCollision(bb);
|
||||
return original.call(world, bb);
|
||||
}
|
||||
int minX = Mth.floor(bb.minX);
|
||||
int minY = Mth.floor(bb.minY);
|
||||
@@ -80,7 +82,7 @@ public class NaturalSpawnerMixin
|
||||
}
|
||||
else
|
||||
{
|
||||
return world.noCollision(bb);
|
||||
return original.call(world, bb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,7 +105,7 @@ public class NaturalSpawnerMixin
|
||||
}
|
||||
else
|
||||
{
|
||||
return world.noCollision(bb);
|
||||
return original.call(world, bb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,7 +125,7 @@ public class NaturalSpawnerMixin
|
||||
((block instanceof FenceGateBlock) && !state.getValue(FenceGateBlock.OPEN))
|
||||
)
|
||||
{
|
||||
if (x == minX || x == maxX || z == minZ || z == maxZ) return world.noCollision(bb);
|
||||
if (x == minX || x == maxX || z == minZ || z == maxZ) return original.call(world, bb);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -133,9 +135,9 @@ public class NaturalSpawnerMixin
|
||||
|
||||
@Redirect(method = "getMobForSpawn", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/entity/EntityType;create(Lnet/minecraft/world/level/Level;)Lnet/minecraft/world/entity/Entity;"
|
||||
target = "Lnet/minecraft/world/entity/EntityType;create(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/EntitySpawnReason;)Lnet/minecraft/world/entity/Entity;"
|
||||
))
|
||||
private static Entity create(EntityType<?> entityType, Level world_1)
|
||||
private static Entity create(final EntityType<?> entityType, final Level world_1, final EntitySpawnReason entitySpawnReason)
|
||||
{
|
||||
if (CarpetSettings.lagFreeSpawning)
|
||||
{
|
||||
@@ -143,11 +145,11 @@ public class NaturalSpawnerMixin
|
||||
if (precookedMobs.containsKey(entityType))
|
||||
//this mob has been <init>'s but not used yet
|
||||
return precookedMobs.get(entityType);
|
||||
Entity e = entityType.create(world_1);
|
||||
Entity e = entityType.create(world_1, entitySpawnReason);
|
||||
precookedMobs.put(entityType, e);
|
||||
return e;
|
||||
}
|
||||
return entityType.create(world_1);
|
||||
return entityType.create(world_1, entitySpawnReason);
|
||||
}
|
||||
|
||||
@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(
|
||||
@@ -176,9 +178,9 @@ public class NaturalSpawnerMixin
|
||||
|
||||
@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/entity/Mob;finalizeSpawn(Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/world/DifficultyInstance;Lnet/minecraft/world/entity/MobSpawnType;Lnet/minecraft/world/entity/SpawnGroupData;)Lnet/minecraft/world/entity/SpawnGroupData;"
|
||||
target = "Lnet/minecraft/world/entity/Mob;finalizeSpawn(Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/world/DifficultyInstance;Lnet/minecraft/world/entity/EntitySpawnReason;Lnet/minecraft/world/entity/SpawnGroupData;)Lnet/minecraft/world/entity/SpawnGroupData;"
|
||||
))
|
||||
private static SpawnGroupData spawnEntity(Mob mobEntity, ServerLevelAccessor serverWorldAccess, DifficultyInstance difficulty, MobSpawnType spawnReason, SpawnGroupData entityData)
|
||||
private static SpawnGroupData spawnEntity(Mob mobEntity, ServerLevelAccessor serverWorldAccess, DifficultyInstance difficulty, EntitySpawnReason spawnReason, SpawnGroupData entityData)
|
||||
{
|
||||
if (!SpawnReporter.mockSpawns) // WorldAccess
|
||||
return mobEntity.finalizeSpawn(serverWorldAccess, difficulty, spawnReason, entityData);
|
||||
@@ -271,17 +273,13 @@ public class NaturalSpawnerMixin
|
||||
@Inject(method = "spawnForChunk", at = @At("HEAD"))
|
||||
// allows to change mobcaps and captures each category try per dimension before it fails due to full mobcaps.
|
||||
private static void checkSpawns(ServerLevel world, LevelChunk chunk, NaturalSpawner.SpawnState info,
|
||||
boolean spawnAnimals, boolean spawnMonsters, boolean shouldSpawnAnimals, CallbackInfo ci)
|
||||
List<MobCategory> list, CallbackInfo ci)
|
||||
{
|
||||
if (SpawnReporter.trackingSpawns())
|
||||
{
|
||||
MobCategory[] var6 = SPAWNING_CATEGORIES;
|
||||
int var7 = var6.length;
|
||||
for (MobCategory entityCategory: list)
|
||||
{
|
||||
|
||||
for(int var8 = 0; var8 < var7; ++var8) {
|
||||
MobCategory entityCategory = var6[var8];
|
||||
if ((spawnAnimals || !entityCategory.isFriendly()) && (spawnMonsters || entityCategory.isFriendly()) && (shouldSpawnAnimals || !entityCategory.isPersistent()) )
|
||||
{
|
||||
ResourceKey<Level> dim = world.dimension(); // getDimensionType;
|
||||
int newCap = entityCategory.getMaxInstancesPerChunk(); //(int) ((double)entityCategory.getCapacity()*(Math.pow(2.0,(SpawnReporter.mobcap_exponent/4))));
|
||||
int int_2 = SpawnReporter.chunkCounts.get(dim); // eligible chunks for spawning
|
||||
@@ -311,7 +309,6 @@ public class NaturalSpawnerMixin
|
||||
//else
|
||||
//full mobcaps - and key in local_spawns will be missing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.Commands;
|
||||
import net.minecraft.server.commands.PerfCommand;
|
||||
import net.minecraft.server.permissions.PermissionCheck;
|
||||
import net.minecraft.server.permissions.PermissionProviderCheck;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(PerfCommand.class)
|
||||
public class PerfCommand_permissionMixin
|
||||
{
|
||||
@Inject(method = "method_37340", at = @At("HEAD"), cancellable = true, remap = false)
|
||||
private static void canRun(CommandSourceStack source, CallbackInfoReturnable<Boolean> cir)
|
||||
@Redirect(method = "register", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/commands/Commands;hasPermission(Lnet/minecraft/server/permissions/PermissionCheck;)Lnet/minecraft/server/permissions/PermissionProviderCheck;"
|
||||
))
|
||||
private static PermissionProviderCheck canRun(PermissionCheck permissionCheck)
|
||||
{
|
||||
cir.setReturnValue(source.hasPermission(CarpetSettings.perfPermissionLevel));
|
||||
return Commands.hasPermission(CarpetSettings.perfPermissionCheck);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.DiggerItem;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.PickaxeItem;
|
||||
import net.minecraft.world.item.Tier;
|
||||
import net.minecraft.world.item.component.Tool;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
@Mixin(PickaxeItem.class)
|
||||
public class PickaxeItem_missingToolsMixin extends DiggerItem
|
||||
{
|
||||
|
||||
protected PickaxeItem_missingToolsMixin(Tier material, TagKey<Block> tag, Properties settings) {
|
||||
super(material, tag, settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDestroySpeed(ItemStack stack, BlockState state) {
|
||||
if (CarpetSettings.missingTools && state.getSoundType() == SoundType.GLASS)
|
||||
{
|
||||
final Tool tool = stack.get(DataComponents.TOOL);
|
||||
return tool != null ? tool.getMiningSpeed(Blocks.STONE.defaultBlockState()) : super.getDestroySpeed(stack, state);
|
||||
}
|
||||
return super.getDestroySpeed(stack, state);
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplie
|
||||
@Mixin(PieceGeneratorSupplier.class)
|
||||
public interface PieceGeneratorSupplier_plopMixin
|
||||
{
|
||||
@Redirect(method = "method_39845", at = @At(
|
||||
@Redirect(method = "lambda$simple$0", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "java/util/function/Predicate.test(Ljava/lang/Object;)Z"
|
||||
), remap = false)
|
||||
|
||||
@@ -2,6 +2,7 @@ package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.EntityTypes;
|
||||
import net.minecraft.world.entity.SpawnPlacementType;
|
||||
import net.minecraft.world.entity.SpawnPlacementTypes;
|
||||
import net.minecraft.world.entity.SpawnPlacements;
|
||||
@@ -14,7 +15,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
public class PiglinBrute_getPlacementTypeMixin {
|
||||
@Inject(method = "getPlacementType", at = @At("HEAD"), cancellable = true)
|
||||
private static void getPlacementType(final EntityType<?> entityType, final CallbackInfoReturnable<SpawnPlacementType> cir) {
|
||||
if (CarpetSettings.piglinsSpawningInBastions && entityType == EntityType.PIGLIN_BRUTE) {
|
||||
if (CarpetSettings.piglinsSpawningInBastions && entityType == EntityTypes.PIGLIN_BRUTE) {
|
||||
cir.setReturnValue(SpawnPlacementTypes.ON_GROUND);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,12 @@ package carpet.mixins;
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.fakes.PistonBlockEntityInterface;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.llamalad7.mixinextras.sugar.Share;
|
||||
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.Level;
|
||||
@@ -11,7 +17,6 @@ import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.CommandBlock;
|
||||
import net.minecraft.world.level.block.DirectionalBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.piston.MovingPistonBlock;
|
||||
import net.minecraft.world.level.block.piston.PistonBaseBlock;
|
||||
import net.minecraft.world.level.block.piston.PistonStructureResolver;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
@@ -33,8 +38,6 @@ public abstract class PistonBaseBlock_movableBEMixin extends DirectionalBlock
|
||||
{
|
||||
super(block$Settings_1);
|
||||
}
|
||||
|
||||
private ThreadLocal<List<BlockEntity>> list1_BlockEntities = new ThreadLocal<>(); //Unneccessary ThreadLocal if client and server use different PistonBlock instances
|
||||
|
||||
@Inject(method = "isPushable", cancellable = true, at = @At(value = "RETURN", ordinal = 3, shift = At.Shift.BEFORE))
|
||||
private static void movableCMD(BlockState blockState_1, Level world_1, BlockPos blockPos_1,
|
||||
@@ -53,7 +56,8 @@ public abstract class PistonBaseBlock_movableBEMixin extends DirectionalBlock
|
||||
//Making PISTON_EXTENSION (BlockPistonMoving) pushable would not work as its createNewTileEntity()-method returns null
|
||||
return block != Blocks.ENDER_CHEST && block != Blocks.ENCHANTING_TABLE &&
|
||||
block != Blocks.END_GATEWAY && block != Blocks.END_PORTAL && block != Blocks.MOVING_PISTON &&
|
||||
block != Blocks.SPAWNER;
|
||||
block != Blocks.SPAWNER
|
||||
&& block != Blocks.SCULK_SENSOR && block != Blocks.CALIBRATED_SCULK_SENSOR; // these have weird behaviour and crashes, #1473, also #1885
|
||||
}
|
||||
|
||||
@Redirect(method = "isPushable", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;hasBlockEntity()Z"))
|
||||
@@ -84,17 +88,17 @@ public abstract class PistonBaseBlock_movableBEMixin extends DirectionalBlock
|
||||
private void onMove(Level world_1, BlockPos blockPos_1, Direction direction_1, boolean boolean_1,
|
||||
CallbackInfoReturnable<Boolean> cir, BlockPos blockPos_2, PistonStructureResolver pistonHandler_1, Map<?, ?> map_1,
|
||||
List<BlockPos> list_1, List<BlockState> list_2, List<?> list_3, BlockState[] blockStates_1,
|
||||
Direction direction_2, int int_2)
|
||||
Direction direction_2, int int_2, @Share("blockEntities") LocalRef<List<BlockEntity>> blockEntities)
|
||||
{
|
||||
//Get the blockEntities and remove them from the world before any magic starts to happen
|
||||
if (CarpetSettings.movableBlockEntities)
|
||||
{
|
||||
list1_BlockEntities.set(Lists.newArrayList());
|
||||
blockEntities.set(Lists.newArrayList());
|
||||
for (int i = 0; i < list_1.size(); ++i)
|
||||
{
|
||||
BlockPos blockpos = list_1.get(i);
|
||||
BlockEntity blockEntity = (list_2.get(i).hasBlockEntity()) ? world_1.getBlockEntity(blockpos) : null;
|
||||
list1_BlockEntities.get().add(blockEntity);
|
||||
blockEntities.get().add(blockEntity);
|
||||
if (blockEntity != null)
|
||||
{
|
||||
//hopefully this call won't have any side effects in the future, such as dropping all the BlockEntity's items
|
||||
@@ -105,35 +109,15 @@ public abstract class PistonBaseBlock_movableBEMixin extends DirectionalBlock
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "moveBlocks", at = @At(value = "INVOKE", shift = At.Shift.BEFORE,
|
||||
target = "Lnet/minecraft/world/level/Level;setBlockEntity(Lnet/minecraft/world/level/block/entity/BlockEntity;)V", ordinal = 0),
|
||||
locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
private void setBlockEntityWithCarried(Level world_1, BlockPos blockPos_1, Direction direction_1, boolean boolean_1,
|
||||
CallbackInfoReturnable<Boolean> cir, BlockPos blockPos_2, PistonStructureResolver pistonHandler_1, Map<?, ?> map_1, List<?> list_1,
|
||||
List<BlockState> list_2, List<?> list_3, BlockState[] blockStates_1, Direction direction_2, int int_2,
|
||||
int int_3, BlockPos blockPos_4, BlockState blockState9, BlockState blockState4)
|
||||
{
|
||||
BlockEntity blockEntityPiston = MovingPistonBlock.newMovingBlockEntity(blockPos_4, blockState4, list_2.get(int_3),
|
||||
direction_1, boolean_1, false);
|
||||
if (CarpetSettings.movableBlockEntities)
|
||||
((PistonBlockEntityInterface) blockEntityPiston).setCarriedBlockEntity(list1_BlockEntities.get().get(int_3));
|
||||
world_1.setBlockEntity(blockEntityPiston);
|
||||
//world_1.setBlockEntity(blockPos_4, blockEntityPiston);
|
||||
}
|
||||
|
||||
@Redirect(method = "moveBlocks", at = @At(value = "INVOKE",
|
||||
|
||||
@WrapOperation(method = "moveBlocks", at = @At(value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/Level;setBlockEntity(Lnet/minecraft/world/level/block/entity/BlockEntity;)V",
|
||||
ordinal = 0))
|
||||
private void dontDoAnything(Level world, BlockEntity blockEntity)
|
||||
private void setCarriedOnMove(Level instance, BlockEntity blockEntity, Operation<Void> original,
|
||||
@Local(ordinal = 1) int index, @Share("blockEntities") LocalRef<List<BlockEntity>> blockEntities)
|
||||
{
|
||||
}
|
||||
|
||||
@Redirect(method = "moveBlocks", at = @At(value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/block/piston/MovingPistonBlock;newMovingBlockEntity(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/Direction;ZZ)Lnet/minecraft/world/level/block/entity/BlockEntity;",
|
||||
ordinal = 0))
|
||||
private BlockEntity returnNull(BlockPos blockPos, BlockState blockState, BlockState blockState2, Direction direction, boolean bl, boolean bl2)
|
||||
{
|
||||
return null;
|
||||
if (CarpetSettings.movableBlockEntities)
|
||||
((PistonBlockEntityInterface) blockEntity).setCarriedBlockEntity(blockEntities.get().get(index));
|
||||
original.call(instance, blockEntity);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.PistonHeadRenderStateInterface;
|
||||
import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState;
|
||||
import net.minecraft.client.renderer.blockentity.state.PistonHeadRenderState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
@Mixin(PistonHeadRenderState.class)
|
||||
public class PistonHeadRenderState_movableBEMixin implements PistonHeadRenderStateInterface {
|
||||
private BlockEntityRenderState blockEntityRenderState;
|
||||
@Override
|
||||
public BlockEntityRenderState getMovedBERenderState() {
|
||||
return blockEntityRenderState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMovedBERenderState(BlockEntityRenderState state) {
|
||||
this.blockEntityRenderState = state;
|
||||
}
|
||||
}
|
||||
@@ -1,59 +1,71 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.fakes.PistonHeadRenderStateInterface;
|
||||
import carpet.fakes.PistonBlockEntityInterface;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.SubmitNodeCollector;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
import net.minecraft.client.renderer.blockentity.PistonHeadRenderer;
|
||||
import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState;
|
||||
import net.minecraft.client.renderer.blockentity.state.PistonHeadRenderState;
|
||||
import net.minecraft.client.renderer.feature.ModelFeatureRenderer;
|
||||
import net.minecraft.client.renderer.state.level.CameraRenderState;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.piston.PistonMovingBlockEntity;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
@Mixin(PistonHeadRenderer.class)
|
||||
public abstract class PistonHeadRenderer_movableBEMixin implements BlockEntityRenderer<PistonMovingBlockEntity>
|
||||
public abstract class PistonHeadRenderer_movableBEMixin implements BlockEntityRenderer<PistonMovingBlockEntity, PistonHeadRenderState>
|
||||
{
|
||||
BlockEntityRenderDispatcher dispatcher;
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void onInitCM(BlockEntityRendererProvider.Context arguments, CallbackInfo ci)
|
||||
private void onInitCM(CallbackInfo ci)
|
||||
{
|
||||
dispatcher = arguments.getBlockEntityRenderDispatcher();
|
||||
dispatcher = Minecraft.getInstance().getBlockEntityRenderDispatcher();
|
||||
}
|
||||
|
||||
@Inject(method = "render", at = @At(value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/renderer/blockentity/PistonHeadRenderer;renderBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;Lnet/minecraft/world/level/Level;ZI)V", ordinal = 3))
|
||||
private void updateRenderBool(PistonMovingBlockEntity pistonBlockEntity_1, float float_1, PoseStack matrixStack_1, MultiBufferSource layeredVertexConsumerStorage_1, int int_1, int int_2, CallbackInfo ci)
|
||||
//private void updateRenderBool(PistonBlockEntity pistonBlockEntity_1, double double_1, double double_2, double double_3, float float_1, class_4587 class_4587_1, class_4597 class_4597_1, int int_1, CallbackInfo ci)
|
||||
@Inject(method = "extractRenderState(Lnet/minecraft/world/level/block/piston/PistonMovingBlockEntity;Lnet/minecraft/client/renderer/blockentity/state/PistonHeadRenderState;FLnet/minecraft/world/phys/Vec3;Lnet/minecraft/client/renderer/feature/ModelFeatureRenderer$CrumblingOverlay;)V",
|
||||
at = @At("RETURN"))
|
||||
private void addBE(PistonMovingBlockEntity pistonMovingBlockEntity, PistonHeadRenderState pistonHeadRenderState, float f, Vec3 vec3, ModelFeatureRenderer.CrumblingOverlay crumblingOverlay, CallbackInfo ci)
|
||||
{
|
||||
if (!((PistonBlockEntityInterface) pistonBlockEntity_1).isRenderModeSet())
|
||||
((PistonBlockEntityInterface) pistonBlockEntity_1).setRenderCarriedBlockEntity(CarpetSettings.movableBlockEntities && ((PistonBlockEntityInterface) pistonBlockEntity_1).getCarriedBlockEntity() != null);
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "render", at = @At("RETURN"), locals = LocalCapture.NO_CAPTURE)
|
||||
private void endMethod3576(PistonMovingBlockEntity pistonBlockEntity_1, float partialTicks, PoseStack matrixStack_1, MultiBufferSource layeredVertexConsumerStorage_1, int int_1, int init_2, CallbackInfo ci)
|
||||
{
|
||||
if (((PistonBlockEntityInterface) pistonBlockEntity_1).getRenderCarriedBlockEntity())
|
||||
if (CarpetSettings.movableBlockEntities)
|
||||
{
|
||||
BlockEntity carriedBlockEntity = ((PistonBlockEntityInterface) pistonBlockEntity_1).getCarriedBlockEntity();
|
||||
if (carriedBlockEntity != null)
|
||||
BlockEntity be = ((PistonBlockEntityInterface) pistonMovingBlockEntity).getCarriedBlockEntity();
|
||||
if (be != null)
|
||||
{
|
||||
// maybe ??? carriedBlockEntity.setPos(pistonBlockEntity_1.getPos());
|
||||
//((BlockEntityRenderDispatcherInterface) BlockEntityRenderDispatcher.INSTANCE).renderBlockEntityOffset(carriedBlockEntity, float_1, int_1, BlockRenderLayer.field_20799, bufferBuilder_1, pistonBlockEntity_1.getRenderOffsetX(float_1), pistonBlockEntity_1.getRenderOffsetY(float_1), pistonBlockEntity_1.getRenderOffsetZ(float_1));
|
||||
matrixStack_1.translate(
|
||||
pistonBlockEntity_1.getXOff(partialTicks),
|
||||
pistonBlockEntity_1.getYOff(partialTicks),
|
||||
pistonBlockEntity_1.getZOff(partialTicks)
|
||||
);
|
||||
dispatcher.render(carriedBlockEntity, partialTicks, matrixStack_1, layeredVertexConsumerStorage_1);
|
||||
|
||||
float progress = pistonMovingBlockEntity.getProgress(f);
|
||||
//System.out.println("progress: " + progress);
|
||||
//if (progress != 0) {
|
||||
BlockEntityRenderState res = dispatcher.tryExtractRenderState(be, f, crumblingOverlay, true);
|
||||
if (res != null) {
|
||||
((PistonHeadRenderStateInterface) pistonHeadRenderState).setMovedBERenderState(res);
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "submit(Lnet/minecraft/client/renderer/blockentity/state/PistonHeadRenderState;Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;Lnet/minecraft/client/renderer/state/level/CameraRenderState;)V",
|
||||
at = @At(value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/renderer/SubmitNodeCollector;submitMovingBlock(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/block/MovingBlockRenderState;I)V",
|
||||
ordinal = 0))
|
||||
private void endMethod(PistonHeadRenderState pistonHeadRenderState, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState cameraRenderState, CallbackInfo ci)
|
||||
//private void endMethod(PistonMovingBlockEntity pistonBlockEntity_1, float partialTicks, PoseStack matrixStack_1, int i, int j, Vec3 vec3, ModelFeatureRenderer.CrumblingOverlay crumblingOverlay, SubmitNodeCollector submitNodeCollector, CallbackInfo ci)
|
||||
//private void endMethod3576(PistonMovingBlockEntity pistonBlockEntity_1, float partialTicks, PoseStack matrixStack_1, MultiBufferSource layeredVertexConsumerStorage_1, int int_1, int init_2, Vec3 cameraPos, CallbackInfo ci)
|
||||
{
|
||||
if (pistonHeadRenderState instanceof PistonHeadRenderStateInterface mbrsi && pistonHeadRenderState.block != null)
|
||||
if (mbrsi.getMovedBERenderState() != null) {
|
||||
BlockEntityRenderState res = mbrsi.getMovedBERenderState();
|
||||
if (res != null) {
|
||||
dispatcher.submit(res, poseStack, submitNodeCollector, cameraRenderState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,10 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.piston.PistonMovingBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import net.minecraft.world.level.storage.TagValueOutput;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import net.minecraft.world.level.storage.ValueOutput;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
@@ -121,7 +125,7 @@ public abstract class PistonMovingBlockEntity_movableBEMixin extends BlockEntity
|
||||
//Handle TNT Explosions or other ways the moving Block is broken
|
||||
//Also /setblock will cause this to be called, and drop e.g. a moving chest's contents.
|
||||
// This is MC-40380 (BlockEntities that aren't Inventories drop stuff when setblock is called )
|
||||
if (CarpetSettings.movableBlockEntities && this.carriedBlockEntity != null && !this.level.isClientSide && this.level.getBlockState(this.worldPosition).getBlock() == Blocks.AIR)
|
||||
if (CarpetSettings.movableBlockEntities && this.carriedBlockEntity != null && !this.level.isClientSide() && this.level.getBlockState(this.worldPosition).getBlock() == Blocks.AIR)
|
||||
{
|
||||
BlockState blockState_2;
|
||||
if (this.isSourcePiston)
|
||||
@@ -134,25 +138,25 @@ public abstract class PistonMovingBlockEntity_movableBEMixin extends BlockEntity
|
||||
}
|
||||
|
||||
@Inject(method = "loadAdditional", at = @At(value = "TAIL"))
|
||||
private void onFromTag(CompoundTag NbtCompound_1, HolderLookup.Provider registries, CallbackInfo ci)
|
||||
private void onFromTag(ValueInput valueInput, CallbackInfo ci)
|
||||
{
|
||||
if (CarpetSettings.movableBlockEntities && NbtCompound_1.contains("carriedTileEntityCM", 10))
|
||||
{
|
||||
if (this.movedState.getBlock() instanceof EntityBlock)
|
||||
this.carriedBlockEntity = ((EntityBlock) (this.movedState.getBlock())).newBlockEntity(worldPosition, movedState);// this.world);
|
||||
if (carriedBlockEntity != null) //Can actually be null, as BlockPistonMoving.createNewTileEntity(...) returns null
|
||||
this.carriedBlockEntity.loadWithComponents(NbtCompound_1.getCompound("carriedTileEntityCM"), registries);
|
||||
setCarriedBlockEntity(carriedBlockEntity);
|
||||
}
|
||||
if (CarpetSettings.movableBlockEntities)
|
||||
valueInput.child("carriedTileEntityCM").ifPresent(tag -> {
|
||||
if (this.movedState.getBlock() instanceof EntityBlock)
|
||||
this.carriedBlockEntity = ((EntityBlock) (this.movedState.getBlock())).newBlockEntity(worldPosition, movedState);// this.world);
|
||||
if (carriedBlockEntity != null) //Can actually be null, as BlockPistonMoving.createNewTileEntity(...) returns null
|
||||
this.carriedBlockEntity.loadWithComponents(tag);
|
||||
setCarriedBlockEntity(carriedBlockEntity);
|
||||
});
|
||||
}
|
||||
|
||||
@Inject(method = "saveAdditional", at = @At(value = "RETURN", shift = At.Shift.BEFORE))
|
||||
private void onToTag(CompoundTag NbtCompound_1, HolderLookup.Provider registries, CallbackInfo ci)
|
||||
private void onToTag(ValueOutput valueOutput, CallbackInfo ci)
|
||||
{
|
||||
if (CarpetSettings.movableBlockEntities && this.carriedBlockEntity != null)
|
||||
if (CarpetSettings.movableBlockEntities && this.carriedBlockEntity != null && valueOutput instanceof TagValueOutput output)
|
||||
{
|
||||
//Leave name "carriedTileEntityCM" instead of "carriedBlockEntityCM" for upgrade compatibility with 1.13.2 movable TE
|
||||
NbtCompound_1.put("carriedTileEntityCM", this.carriedBlockEntity.saveWithoutMetadata(registries));
|
||||
this.carriedBlockEntity.saveWithoutMetadata(output.child("carriedTileEntityCM"));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded 100 of 264 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user