delete stuff

This commit is contained in:
lcy0x1
2024-06-22 20:03:26 +08:00
parent d6924bf5aa
commit ec06408563
56 changed files with 257 additions and 1228 deletions

View File

@@ -1,7 +1,8 @@
package dev.xkmc.l2core.base.effects; package dev.xkmc.l2core.base.effects;
import dev.xkmc.l2core.capability.attachment.GeneralCapabilityTemplate; import dev.xkmc.l2core.capability.attachment.GeneralCapabilityTemplate;
import dev.xkmc.l2serial.serialization.SerialClass; import dev.xkmc.l2serial.serialization.marker.SerialClass;
import net.minecraft.core.Holder;
import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
@@ -12,6 +13,6 @@ import java.util.TreeMap;
@SerialClass @SerialClass
public class ClientEffectCap extends GeneralCapabilityTemplate<LivingEntity, ClientEffectCap> { public class ClientEffectCap extends GeneralCapabilityTemplate<LivingEntity, ClientEffectCap> {
public final Map<MobEffect, Integer> map = new TreeMap<>(Comparator.comparing(MobEffect::getDescriptionId)); public final Map<Holder<MobEffect>, Integer> map = new TreeMap<>(Comparator.comparing(Holder::getRegisteredName));
} }

View File

@@ -1,5 +1,6 @@
package dev.xkmc.l2core.base.effects; package dev.xkmc.l2core.base.effects;
import net.minecraft.core.Holder;
import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffectInstance;
@@ -11,7 +12,7 @@ public class EffectBuilder {
this.ins = ins; this.ins = ins;
} }
public EffectBuilder(MobEffect effect) { public EffectBuilder(Holder<MobEffect> effect) {
this.ins = new MobEffectInstance(effect, 1, 0); this.ins = new MobEffectInstance(effect, 1, 0);
} }

View File

@@ -1,13 +1,13 @@
package dev.xkmc.l2core.base.effects; package dev.xkmc.l2core.base.effects;
import dev.xkmc.l2core.init.events.ClientEffectRenderEvents; import dev.xkmc.l2core.events.ClientEffectRenderEvents;
import dev.xkmc.l2serial.network.SerialPacketBase; import dev.xkmc.l2serial.network.SerialPacketBase;
import dev.xkmc.l2serial.serialization.SerialClass; import net.minecraft.core.Holder;
import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public record EffectToClient(int entity, MobEffect effect, boolean exist, int level) public record EffectToClient(int entity, Holder<MobEffect> effect, boolean exist, int level)
implements SerialPacketBase<EffectToClient> { implements SerialPacketBase<EffectToClient> {
@Override @Override

View File

@@ -4,7 +4,6 @@ import dev.xkmc.l2core.base.effects.api.ForceEffect;
import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.neoforged.bus.api.Event;
import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.EventHooks; import net.neoforged.neoforge.event.EventHooks;
import net.neoforged.neoforge.event.entity.living.MobEffectEvent; import net.neoforged.neoforge.event.entity.living.MobEffectEvent;
@@ -15,53 +14,46 @@ import java.util.function.Predicate;
public class EffectUtil { public class EffectUtil {
public enum AddReason {
NONE, PROF, FORCE, SKILL, SELF
}
private static final ThreadLocal<AddReason> REASON = new ThreadLocal<>();
/** /**
* force add effect, make hard not override * force add effect, make hard not override
* for icon use only, such as Arcane Mark on Wither and Ender Dragon * for icon use only, such as Arcane Mark on Wither and Ender Dragon
*/ */
private static void forceAddEffect(LivingEntity e, MobEffectInstance ins, @Nullable Entity source) { private static void forceAddEffect(LivingEntity e, MobEffectInstance ins, @Nullable Entity source) {
MobEffectInstance effectinstance = e.getActiveEffectsMap().get(ins.getEffect()); MobEffectInstance old = e.activeEffects.get(ins.getEffect());
var event = new ForceAddEffectEvent(e, ins); var event = new ForceAddEffectEvent(e, ins);
NeoForge.EVENT_BUS.post(event); NeoForge.EVENT_BUS.post(event);
if (event.getResult() == Event.Result.DENY) { if (event.isCanceled()) {
return; return;
} }
NeoForge.EVENT_BUS.post(new MobEffectEvent.Added(e, effectinstance, ins, source)); NeoForge.EVENT_BUS.post(new MobEffectEvent.Added(e, old, ins, source));
if (effectinstance == null) { if (old == null) {
e.getActiveEffectsMap().put(ins.getEffect(), ins); e.activeEffects.put(ins.getEffect(), ins);
e.onEffectAdded(ins, source); e.onEffectAdded(ins, source);
} else if (effectinstance.update(ins)) { ins.onEffectAdded(e);
e.onEffectUpdated(effectinstance, true, source); } else if (old.update(ins)) {
e.onEffectUpdated(old, true, source);
} }
ins.onEffectStarted(e);
} }
public static void addEffect(LivingEntity entity, MobEffectInstance ins, AddReason reason, @Nullable Entity source) { public static void addEffect(LivingEntity entity, MobEffectInstance ins, @Nullable Entity source) {
if (entity == source)
reason = AddReason.SELF;
if (ins.getEffect() instanceof ForceEffect)
reason = AddReason.FORCE;
ins = new MobEffectInstance(ins.getEffect(), ins.getDuration(), ins.getAmplifier(), ins = new MobEffectInstance(ins.getEffect(), ins.getDuration(), ins.getAmplifier(),
ins.isAmbient(), reason != AddReason.FORCE && ins.isVisible(), ins.showIcon()); ins.isAmbient(), ins.isVisible(), ins.showIcon());
REASON.set(reason);
if (ins.getEffect() instanceof ForceEffect) if (ins.getEffect() instanceof ForceEffect)
forceAddEffect(entity, ins, source); forceAddEffect(entity, ins, source);
else if (ins.getEffect().isInstantenous()) else if (ins.getEffect().value().isInstantenous())
ins.getEffect().applyInstantenousEffect(null, null, entity, ins.getAmplifier(), 1); ins.getEffect().value().applyInstantenousEffect(null, null, entity, ins.getAmplifier(), 1);
else entity.addEffect(ins, source); else entity.addEffect(ins, source);
REASON.set(AddReason.NONE);
} }
public static void refreshEffect(LivingEntity entity, MobEffectInstance ins, AddReason reason, Entity source) { public static void refreshEffect(LivingEntity entity, MobEffectInstance ins, Entity source) {
if (ins.duration < 40) ins.duration = 40; if (ins.duration < 40) ins.duration = 40;
MobEffectInstance cur = entity.getEffect(ins.getEffect()); MobEffectInstance cur = entity.getEffect(ins.getEffect());
if (cur == null || cur.getAmplifier() < ins.getAmplifier() || cur.getAmplifier() == ins.getAmplifier() && cur.getDuration() < ins.getDuration() / 2) if (cur == null ||
addEffect(entity, ins, reason, source); cur.getAmplifier() < ins.getAmplifier() ||
cur.getAmplifier() == ins.getAmplifier() &&
cur.getDuration() < ins.getDuration() / 2
) addEffect(entity, ins, source);
} }
public static void removeEffect(LivingEntity entity, Predicate<MobEffectInstance> pred) { public static void removeEffect(LivingEntity entity, Predicate<MobEffectInstance> pred) {
@@ -76,9 +68,4 @@ public class EffectUtil {
} }
} }
public static AddReason getReason() {
AddReason ans = REASON.get();
return ans == null ? AddReason.NONE : ans;
}
} }

View File

@@ -3,11 +3,11 @@ package dev.xkmc.l2core.base.effects;
import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.neoforged.bus.api.Event; import net.neoforged.bus.api.Event;
import net.neoforged.bus.api.ICancellableEvent;
import net.neoforged.neoforge.event.entity.living.MobEffectEvent; import net.neoforged.neoforge.event.entity.living.MobEffectEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@Event.HasResult public class ForceAddEffectEvent extends MobEffectEvent implements ICancellableEvent {
public class ForceAddEffectEvent extends MobEffectEvent {
public ForceAddEffectEvent(LivingEntity living, @NotNull MobEffectInstance effectInstance) { public ForceAddEffectEvent(LivingEntity living, @NotNull MobEffectInstance effectInstance) {
super(living, effectInstance); super(living, effectInstance);

View File

@@ -1,49 +0,0 @@
package dev.xkmc.l2core.base.entity;
import dev.xkmc.l2serial.serialization.SerialClass;
import dev.xkmc.l2serial.serialization.codec.PacketCodec;
import dev.xkmc.l2serial.serialization.codec.TagCodec;
import dev.xkmc.l2serial.util.Wrappers;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.Level;
import net.neoforged.neoforge.entity.IEntityWithComplexSpawn;
import javax.annotation.ParametersAreNonnullByDefault;
@SerialClass
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public abstract class BaseEntity extends Entity implements IEntityWithComplexSpawn {
public BaseEntity(EntityType<?> type, Level world) {
super(type, world);
}
@Override
protected void addAdditionalSaveData(CompoundTag tag) {
tag.put("auto-serial", TagCodec.toTag(new CompoundTag(), this));
}
@Override
protected void readAdditionalSaveData(CompoundTag tag) {
if (!tag.contains("auto-serial"))
return;
Wrappers.run(() -> TagCodec.fromTag(tag.getCompound("auto-serial"), this.getClass(), this, f -> true));
}
@Override
public void writeSpawnData(FriendlyByteBuf buffer) {
PacketCodec.to(buffer, this);
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Override
public void readSpawnData(FriendlyByteBuf data) {
PacketCodec.from(data, (Class) this.getClass(), this);
}
}

View File

@@ -1,8 +0,0 @@
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
package dev.xkmc.l2core.base.entity;
import net.minecraft.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@@ -1,29 +0,0 @@
package dev.xkmc.l2core.base.explosion;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Explosion;
public class BaseExplosion extends Explosion {
public final BaseExplosionContext base;
public final ModExplosionContext mod;
public final VanillaExplosionContext mc;
public final ParticleExplosionContext particle;
public BaseExplosion(BaseExplosionContext base, VanillaExplosionContext mc, ModExplosionContext mod, ParticleExplosionContext particle) {
super(base.level(), mc.entity(), mc.source(), mc.calculator(), base.x(), base.y(), base.z(), base.r(), mc.fire(), mc.type(),
particle.small(), particle.large(), particle.sound());
this.base = base;
this.mod = mod;
this.mc = mc;
this.particle = particle;
}
/**
* return false to cancel hurt
*/
public boolean hurtEntity(Entity entity) {
return mod.hurtEntity(entity);
}
}

View File

@@ -1,6 +0,0 @@
package dev.xkmc.l2core.base.explosion;
import net.minecraft.world.level.Level;
public record BaseExplosionContext(Level level, double x, double y, double z, float r) {
}

View File

@@ -1,37 +0,0 @@
package dev.xkmc.l2core.base.explosion;
import net.minecraft.network.protocol.game.ClientboundExplodePacket;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level;
import net.neoforged.neoforge.event.EventHooks;
public class ExplosionHandler {
public static void explode(BaseExplosion exp) {
if (exp.base.level().isClientSide()) return;
if (EventHooks.onExplosionStart(exp.base.level(), exp)) return;
exp.explode();
Level level = exp.base.level();
exp.finalizeExplosion(level.isClientSide());
double x = exp.base.x();
double y = exp.base.y();
double z = exp.base.z();
float r = exp.base.r();
boolean flag = exp.mc.type() == Explosion.BlockInteraction.KEEP;
if (flag) {
exp.clearToBlow();
}
for (Player player : level.players()) {
if (player instanceof ServerPlayer serverplayer) {
if (serverplayer.distanceToSqr(x, y, z) < 4096.0D) {
serverplayer.connection.send(new ClientboundExplodePacket(x, y, z, r,
exp.getToBlow(), exp.getHitPlayers().get(serverplayer), exp.mc.type(),
exp.particle.small(), exp.particle.large(), exp.particle.sound()));
}
}
}
}
}

View File

@@ -1,12 +0,0 @@
package dev.xkmc.l2core.base.explosion;
import net.minecraft.world.entity.Entity;
public interface ModExplosionContext {
/**
* return false to cancel damage
*/
boolean hurtEntity(Entity entity);
}

View File

@@ -1,9 +0,0 @@
package dev.xkmc.l2core.base.explosion;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.sounds.SoundEvent;
public record ParticleExplosionContext(ParticleOptions small,
ParticleOptions large,
SoundEvent sound) {
}

View File

@@ -1,36 +0,0 @@
package dev.xkmc.l2core.base.explosion;
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.GameRules;
import net.minecraft.world.level.Level;
import net.neoforged.neoforge.event.EventHooks;
import javax.annotation.Nullable;
public record VanillaExplosionContext(@Nullable Entity entity, @Nullable DamageSource source,
@Nullable ExplosionDamageCalculator calculator,
boolean fire, Explosion.BlockInteraction type) {
public VanillaExplosionContext(Level level, @Nullable Entity entity, @Nullable DamageSource source,
@Nullable ExplosionDamageCalculator calculator,
boolean fire, Level.ExplosionInteraction type) {
this(entity, source, calculator, fire, getType(level, entity, type));
}
private static Explosion.BlockInteraction getType(Level level, @Nullable Entity entity, Level.ExplosionInteraction type) {
return switch (type) {
case NONE -> Explosion.BlockInteraction.KEEP;
case BLOCK -> level.getDestroyType(GameRules.RULE_BLOCK_EXPLOSION_DROP_DECAY);
case MOB -> EventHooks.getMobGriefingEvent(level, entity instanceof LivingEntity le ? le : null) ?
level.getDestroyType(GameRules.RULE_MOB_EXPLOSION_DROP_DECAY) :
Explosion.BlockInteraction.KEEP;
case TNT -> level.getDestroyType(GameRules.RULE_TNT_EXPLOSION_DROP_DECAY);
case BLOW -> Explosion.BlockInteraction.TRIGGER_BLOCK;
};
}
}

View File

@@ -1,8 +0,0 @@
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
package dev.xkmc.l2core.base.explosion;
import net.minecraft.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@@ -1,6 +1,7 @@
package dev.xkmc.l2core.base.menu.base; package dev.xkmc.l2core.base.menu.base;
import dev.xkmc.l2serial.serialization.SerialClass; import dev.xkmc.l2serial.serialization.marker.SerialClass;
import dev.xkmc.l2serial.serialization.marker.SerialField;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
@@ -17,7 +18,7 @@ import java.util.HashMap;
public record MenuLayoutConfig(int height, HashMap<String, Rect> side, HashMap<String, Rect> comp) { public record MenuLayoutConfig(int height, HashMap<String, Rect> side, HashMap<String, Rect> comp) {
public static ResourceLocation getTexture(ResourceLocation id) { public static ResourceLocation getTexture(ResourceLocation id) {
return new ResourceLocation(id.getNamespace(), "textures/gui/container/" + id.getPath() + ".png"); return ResourceLocation.fromNamespaceAndPath(id.getNamespace(), "textures/gui/container/" + id.getPath() + ".png");
} }
/** /**
@@ -109,7 +110,7 @@ public record MenuLayoutConfig(int height, HashMap<String, Rect> side, HashMap<S
public static final Rect ZERO = new Rect(); public static final Rect ZERO = new Rect();
@SerialClass.SerialField @SerialField
public int x, y, w, h, rx = 1, ry = 1; public int x, y, w, h, rx = 1, ry = 1;
public Rect() { public Rect() {
@@ -125,7 +126,7 @@ public record MenuLayoutConfig(int height, HashMap<String, Rect> side, HashMap<S
public final ResourceLocation id; public final ResourceLocation id;
public MenuLayoutConfig parent(){ public MenuLayoutConfig parent() {
return MenuLayoutConfig.this; return MenuLayoutConfig.this;
} }

View File

@@ -6,7 +6,7 @@ import net.minecraft.resources.ResourceLocation;
public record SpriteManager(ResourceLocation id) { public record SpriteManager(ResourceLocation id) {
public SpriteManager(String modid, String path) { public SpriteManager(String modid, String path) {
this(new ResourceLocation(modid, path)); this(ResourceLocation.fromNamespaceAndPath(modid, path));
} }
public MenuLayoutConfig get() { public MenuLayoutConfig get() {

View File

@@ -1,40 +0,0 @@
package dev.xkmc.l2core.base.overlay;
import dev.xkmc.l2core.init.L2LibraryConfig;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import net.neoforged.neoforge.client.gui.overlay.ExtendedGui;
import net.neoforged.neoforge.client.gui.overlay.IGuiOverlay;
import java.util.List;
public abstract class InfoSideBar<S extends SideBar.Signature<S>> extends SideBar<S> implements IGuiOverlay {
public InfoSideBar(float duration, float ease) {
super(duration, ease);
}
@Override
public void render(ExtendedGui gui, GuiGraphics g, float partialTick, int width, int height) {
if (!ease(gui.getGuiTicks() + partialTick))
return;
var text = getText();
if (text.isEmpty()) return;
int anchor = L2LibraryConfig.CLIENT.infoAnchor.get();
int y = height * anchor / 2;
int w = (int) (width * L2LibraryConfig.CLIENT.infoMaxWidth.get());
new TextBox(g, 0, anchor, getXOffset(width), y, w)
.renderLongText(Minecraft.getInstance().font, text);
}
protected abstract List<Component> getText();
@Override
protected int getXOffset(int width) {
float progress = (max_ease - ease_time) / max_ease;
return Math.round(-progress * width / 2 + 8);
}
}

View File

@@ -1,46 +0,0 @@
package dev.xkmc.l2core.base.overlay;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.world.item.ItemStack;
import java.util.List;
public abstract class ItemSelSideBar<S extends SideBar.Signature<S>> extends SelectionSideBar<ItemStack, S> {
public ItemSelSideBar(float duration, float ease) {
super(duration, ease);
}
@Override
protected void renderEntry(Context ctx, ItemStack stack, int i, int selected) {
boolean shift = Minecraft.getInstance().options.keyShift.isDown();
int y = 18 * i + ctx.y0();
renderSelection(ctx.g(), ctx.x0(), y, shift ? 127 : 64, isAvailable(stack), selected == i);
if (selected == i) {
if (!stack.isEmpty() && ease_time == max_ease) {
boolean onCenter = onCenter();
ctx.g().renderTooltip(ctx.font(), stack.getHoverName(), 0, 0);
TextBox box = new TextBox(ctx.g(), onCenter ? 0 : 2, 1, ctx.x0() + (onCenter ? 22 : -6), y + 8, -1);
box.renderLongText(ctx.font(), List.of(stack.getHoverName()));
}
}
ctx.renderItem(stack, ctx.x0(), y);
}
public void renderSelection(GuiGraphics g, int x, int y, int a, boolean available, boolean selected) {
if (available) {
OverlayUtil.fillRect(g, x, y, 16, 16, color(255, 255, 255, a));
} else {
OverlayUtil.fillRect(g, x, y, 16, 16, color(255, 0, 0, a));
}
if (selected) {
OverlayUtil.drawRect(g, x, y, 16, 16, color(255, 170, 0, 255));
}
}
public static int color(int r, int g, int b, int a) {
return a << 24 | r << 16 | g << 8 | b;
}
}

View File

@@ -1,43 +0,0 @@
package dev.xkmc.l2core.base.overlay;
import net.minecraft.client.gui.GuiGraphics;
public record L2TooltipRenderUtil(GuiGraphics fill, int bg, int bs, int be) {
public void renderTooltipBackground(int x, int y, int w, int h, int z) {
int x1 = x - 3;
int y1 = y - 3;
int w1 = w + 3 + 3;
int h1 = h + 3 + 3;
renderHorizontalLine(x1, y1 - 1, w1, z, bg);
renderHorizontalLine(x1, y1 + h1, w1, z, bg);
renderRectangle(x1, y1, w1, h1, z, bg);
renderVerticalLine(x1 - 1, y1, h1, z, bg);
renderVerticalLine(x1 + w1, y1, h1, z, bg);
renderFrameGradient(x1, y1 + 1, w1, h1, z, bs, be);
}
private void renderFrameGradient(int x, int y, int w, int h, int z, int c0, int c1) {
renderVerticalLineGradient(x, y, h - 2, z, c0, c1);
renderVerticalLineGradient(x + w - 1, y, h - 2, z, c0, c1);
renderHorizontalLine(x, y - 1, w, z, c0);
renderHorizontalLine(x, y - 1 + h - 1, w, z, c1);
}
private void renderVerticalLine(int x, int y, int h, int z, int c) {
fill.fillGradient(x, y, x + 1, y + h, z, c, c);
}
private void renderVerticalLineGradient(int x, int y, int h, int z, int c0, int c1) {
fill.fillGradient(x, y, x + 1, y + h, z, c0, c1);
}
private void renderHorizontalLine(int x, int y, int w, int z, int c) {
fill.fillGradient(x, y, x + w, y + 1, z, c, c);
}
private void renderRectangle(int x, int y, int w, int h, int z, int c) {
fill.fillGradient(x, y, x + w, y + h, z, c, c);
}
}

View File

@@ -1,105 +0,0 @@
package dev.xkmc.l2core.base.overlay;
import dev.xkmc.l2core.init.L2LibraryConfig;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipPositioner;
import net.minecraft.client.gui.screens.inventory.tooltip.TooltipRenderUtil;
import net.minecraft.network.chat.Component;
import org.joml.Vector2i;
import org.joml.Vector2ic;
import java.util.List;
public class OverlayUtil implements ClientTooltipPositioner {
private static int getBGColor() {
return (int) (Math.round(L2LibraryConfig.CLIENT.infoAlpha.get() * 255)) << 24 | 0x100010;
}
public int bg = getBGColor();
public int bs = 0x505000FF;
public int be = 0x5028007f;
public int tc = 0xFFFFFFFF;
protected final GuiGraphics g;
protected final int x0, y0, maxW;
public OverlayUtil(GuiGraphics g, int x0, int y0, int maxW) {
this.g = g;
this.x0 = x0;
this.y0 = y0;
this.maxW = maxW < 0 ? getMaxWidth() : maxW;
}
public int getMaxWidth() {
return g.guiWidth() / 4;
}
public void renderLongText(Font font, List<Component> list) {
List<ClientTooltipComponent> ans = list.stream().flatMap(text -> font.split(text, maxW).stream())
.map(ClientTooltipComponent::create).toList();
renderTooltipInternal(font, ans);
}
public void renderTooltipInternal(Font font, List<ClientTooltipComponent> list) {
if (list.isEmpty()) return;
int w = 0;
int h = list.size() == 1 ? -2 : 0;
for (ClientTooltipComponent c : list) {
int wi = c.getWidth(font);
if (wi > w) {
w = wi;
}
h += c.getHeight();
}
int wf = w;
int hf = h;
Vector2ic pos = positionTooltip(g.guiWidth(), g.guiHeight(), x0, y0, wf, hf);
int xf = pos.x();
int yf = pos.y();
g.pose().pushPose();
int z = 400;
g.drawManaged(() -> TooltipRenderUtil.renderTooltipBackground(g, xf, yf, wf, hf, z, bg, bg, bs, be));
g.pose().translate(0.0F, 0.0F, z);
int yi = yf;
for (int i = 0; i < list.size(); ++i) {
ClientTooltipComponent c = list.get(i);
c.renderText(font, xf, yi, g.pose().last().pose(), g.bufferSource());
yi += c.getHeight() + (i == 0 ? 2 : 0);
}
yi = yf;
for (int i = 0; i < list.size(); ++i) {
ClientTooltipComponent c = list.get(i);
c.renderImage(font, xf, yi, g);
yi += c.getHeight() + (i == 0 ? 2 : 0);
}
g.pose().popPose();
}
@Override
public Vector2ic positionTooltip(int gw, int gh, int x, int y, int tw, int th) {
if (x < 0) x = Math.round(gw / 8f);
if (y < 0) y = Math.round((gh - th) / 2f);
return new Vector2i(x, y);
}
/**
* specifies outer size
*/
public static void fillRect(GuiGraphics g, int x, int y, int w, int h, int col) {
g.fill(x, y, x + w, y + h, col);
}
/**
* specifies inner size
*/
public static void drawRect(GuiGraphics g, int x, int y, int w, int h, int col) {
fillRect(g, x - 1, y - 1, w + 2, 1, col);
fillRect(g, x - 1, y - 1, 1, h + 2, col);
fillRect(g, x - 1, y + h, w + 2, 1, col);
fillRect(g, x + w, y - 1, 1, h + 2, col);
}
}

View File

@@ -1,61 +0,0 @@
package dev.xkmc.l2core.base.overlay;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.client.gui.overlay.ExtendedGui;
import net.neoforged.neoforge.client.gui.overlay.IGuiOverlay;
import java.util.List;
public abstract class SelectionSideBar<T, S extends SideBar.Signature<S>> extends SideBar<S> implements IGuiOverlay {
public SelectionSideBar(float duration, float ease) {
super(duration, ease);
}
public abstract Pair<List<T>, Integer> getItems();
public abstract boolean isAvailable(T t);
public abstract boolean onCenter();
public void initRender() {
}
@Override
public void render(ExtendedGui gui, GuiGraphics g, float partialTick, int width, int height) {
if (!ease(gui.getGuiTicks() + partialTick))
return;
initRender();
gui.setupOverlayRenderState(true, false);
int x0 = this.getXOffset(width);
int y0 = this.getYOffset(height);
Context ctx = new Context(gui, g, partialTick, Minecraft.getInstance().font, x0, y0);
renderContent(ctx);
}
public void renderContent(Context ctx) {
Pair<List<T>, Integer> content = getItems();
var list = content.getFirst();
for (int i = 0; i < list.size(); i++) {
renderEntry(ctx, list.get(i), i, content.getSecond());
}
}
protected abstract void renderEntry(Context ctx, T t, int index, int select);
public record Context(ExtendedGui gui, GuiGraphics g, float pTick, Font font, int x0, int y0) {
public void renderItem(ItemStack stack, int x, int y) {
if (!stack.isEmpty()) {
g.renderItem(stack, x, y);
g.renderItemDecorations(font, stack, x, y);
}
}
}
}

View File

@@ -1,95 +0,0 @@
package dev.xkmc.l2core.base.overlay;
import net.minecraft.client.Minecraft;
import javax.annotation.Nullable;
public abstract class SideBar<S extends SideBar.Signature<S>> {
public interface Signature<S extends Signature<S>> {
boolean shouldRefreshIdle(SideBar<?> sideBar, @Nullable S old);
}
public record IntSignature(int val) implements Signature<IntSignature> {
@Override
public boolean shouldRefreshIdle(SideBar<?> sideBar, @Nullable SideBar.IntSignature old) {
return old == null || val != old.val;
}
}
protected final float max_time;
protected final float max_ease;
@Nullable
protected S prev;
protected float idle = 0;
protected float ease_time = 0;
protected float prev_time = -1;
public SideBar(float duration, float ease) {
this.max_time = duration;
this.max_ease = ease;
}
public abstract S getSignature();
public abstract boolean isScreenOn();
protected boolean isOnHold() {
return Minecraft.getInstance().options.keyShift.isDown();
}
protected boolean ease(float current_time) {
if (!isScreenOn()) {
prev = null;
idle = max_time;
ease_time = 0;
prev_time = -1;
return false;
}
float time_diff = prev_time < 0 ? 0 : (current_time - prev_time);
prev_time = current_time;
S signature = getSignature();
if (signature.shouldRefreshIdle(this, prev) || isOnHold()) {
idle = 0;
} else {
idle += time_diff;
}
prev = signature;
if (idle < max_time) {
if (ease_time < max_ease) {
ease_time += time_diff;
if (ease_time > max_ease) {
ease_time = max_ease;
}
}
} else {
if (ease_time > 0) {
ease_time -= time_diff;
if (ease_time < 0) {
ease_time = 0;
}
}
}
return ease_time > 0;
}
public boolean isRendering() {
return isScreenOn() && ease_time > 0;
}
protected int getXOffset(int width) {
return 0;
}
protected int getYOffset(int height) {
return 0;
}
}

View File

@@ -1,30 +0,0 @@
package dev.xkmc.l2core.base.overlay;
import net.minecraft.client.gui.GuiGraphics;
import org.joml.Vector2i;
import org.joml.Vector2ic;
public class TextBox extends OverlayUtil {
private final int anchorX, anchorY;
public TextBox(GuiGraphics g, int anchorX, int anchorY, int x, int y, int width) {
super(g, x, y, width);
this.anchorX = anchorX;
this.anchorY = anchorY;
}
@Override
public Vector2ic positionTooltip(int gw, int gh, int x, int y, int tw, int th) {
return new Vector2i(x - tw * anchorX / 2, y - th * anchorY / 2);
}
@Override
public int getMaxWidth() {
if (anchorX == 0) return g.guiWidth() - x0 - 8;
if (anchorX == 1) return Math.max(x0 / 2 - 4, g.guiWidth() - x0 / 2 - 4);
if (anchorX == 2) return x0 - 8;
return g.guiWidth();
}
}

View File

@@ -1,8 +0,0 @@
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
package dev.xkmc.l2core.base.overlay;
import net.minecraft.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@@ -1,11 +1,12 @@
package dev.xkmc.l2core.base.tile; package dev.xkmc.l2core.base.tile;
import dev.xkmc.l2core.util.ServerOnly; import dev.xkmc.l2core.util.ServerOnly;
import dev.xkmc.l2serial.serialization.SerialClass;
import dev.xkmc.l2serial.serialization.codec.TagCodec; import dev.xkmc.l2serial.serialization.codec.TagCodec;
import dev.xkmc.l2serial.util.Wrappers; import dev.xkmc.l2serial.serialization.marker.SerialClass;
import dev.xkmc.l2serial.serialization.marker.SerialField;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
@@ -24,16 +25,16 @@ public class BaseBlockEntity extends BlockEntity {
} }
@Override @Override
public void load(CompoundTag tag) { public void loadAdditional(CompoundTag tag, HolderLookup.Provider pvd) {
super.load(tag); super.loadAdditional(tag, pvd);
if (tag.contains("auto-serial")) if (tag.contains("auto-serial"))
Wrappers.run(() -> TagCodec.fromTag(tag.getCompound("auto-serial"), getClass(), this, f -> true)); new TagCodec(pvd).fromTag(tag.getCompound("auto-serial"), getClass(), this);
} }
@Override @Override
public void saveAdditional(CompoundTag tag) { public void saveAdditional(CompoundTag tag, HolderLookup.Provider pvd) {
super.saveAdditional(tag); super.saveAdditional(tag, pvd);
CompoundTag ser = Wrappers.get(() -> TagCodec.toTag(new CompoundTag(), getClass(), this, f -> true)); CompoundTag ser = new TagCodec(pvd).toTag(new CompoundTag(), getClass(), this);
if (ser != null) tag.put("auto-serial", ser); if (ser != null) tag.put("auto-serial", ser);
} }
@@ -53,9 +54,10 @@ public class BaseBlockEntity extends BlockEntity {
* Generate data packet from server to client, called from getUpdatePacket() * Generate data packet from server to client, called from getUpdatePacket()
*/ */
@Override @Override
public CompoundTag getUpdateTag() { public CompoundTag getUpdateTag(HolderLookup.Provider pvd) {
CompoundTag ans = super.getUpdateTag(); CompoundTag ans = super.getUpdateTag(pvd);
CompoundTag ser = Wrappers.get(() -> TagCodec.toTag(new CompoundTag(), getClass(), this, SerialClass.SerialField::toClient)); CompoundTag ser = new TagCodec(pvd).pred(SerialField::toClient)
.toTag(new CompoundTag(), getClass(), this);
if (ser != null) ans.put("auto-serial", ser); if (ser != null) ans.put("auto-serial", ser);
return ans; return ans;
} }

View File

@@ -39,7 +39,7 @@ public class BaseContainer<T extends BaseContainer<T>> extends SimpleContainer i
for (ItemStack stack : items) { for (ItemStack stack : items) {
if (stack.isEmpty()) if (stack.isEmpty())
ans++; ans++;
else if (ItemStack.isSameItemSameTags(stack, add) && else if (ItemStack.isSameItemSameComponents(stack, add) &&
stack.getCount() + add.getCount() <= stack.getCount() + add.getCount() <=
Math.min(stack.getMaxStackSize(), getMaxStackSize())) { Math.min(stack.getMaxStackSize(), getMaxStackSize())) {
return true; return true;
@@ -61,7 +61,7 @@ public class BaseContainer<T extends BaseContainer<T>> extends SimpleContainer i
public boolean canRecipeAddItem(ItemStack stack) { public boolean canRecipeAddItem(ItemStack stack) {
stack = stack.copy(); stack = stack.copy();
for (ItemStack slot : this.items) { for (ItemStack slot : this.items) {
if (slot.isEmpty() || ItemStack.isSameItemSameTags(slot, stack)) { if (slot.isEmpty() || ItemStack.isSameItemSameComponents(slot, stack)) {
int cap = Math.min(getMaxStackSize(), slot.getMaxStackSize()); int cap = Math.min(getMaxStackSize(), slot.getMaxStackSize());
int amount = Math.min(stack.getCount(), cap - slot.getCount()); int amount = Math.min(stack.getCount(), cap - slot.getCount());
if (amount > 0) { if (amount > 0) {

View File

@@ -1,7 +1,8 @@
package dev.xkmc.l2core.base.tile; package dev.xkmc.l2core.base.tile;
import dev.xkmc.l2serial.serialization.SerialClass;
import dev.xkmc.l2serial.serialization.codec.AliasCollection; import dev.xkmc.l2serial.serialization.codec.AliasCollection;
import dev.xkmc.l2serial.serialization.marker.SerialClass;
import dev.xkmc.l2serial.serialization.marker.SerialField;
import net.minecraft.core.NonNullList; import net.minecraft.core.NonNullList;
import net.neoforged.neoforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.FluidStack;
import net.neoforged.neoforge.fluids.capability.IFluidHandler; import net.neoforged.neoforge.fluids.capability.IFluidHandler;
@@ -21,7 +22,7 @@ public class BaseTank implements IFluidHandler, AliasCollection<FluidStack> {
private Predicate<FluidStack> predicate = e -> true; private Predicate<FluidStack> predicate = e -> true;
private BooleanSupplier allowExtract = () -> true; private BooleanSupplier allowExtract = () -> true;
@SerialClass.SerialField @SerialField
public NonNullList<FluidStack> list; public NonNullList<FluidStack> list;
private int click_max; private int click_max;
@@ -82,7 +83,7 @@ public class BaseTank implements IFluidHandler, AliasCollection<FluidStack> {
int filled = 0; int filled = 0;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
FluidStack stack = list.get(i); FluidStack stack = list.get(i);
if (stack.isFluidEqual(resource)) { if (FluidStack.isSameFluidSameComponents(stack, resource)) {
int remain = capacity - stack.getAmount(); int remain = capacity - stack.getAmount();
int fill = Math.min(to_fill, remain); int fill = Math.min(to_fill, remain);
filled += fill; filled += fill;
@@ -123,7 +124,7 @@ public class BaseTank implements IFluidHandler, AliasCollection<FluidStack> {
int drained = 0; int drained = 0;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
FluidStack stack = list.get(i); FluidStack stack = list.get(i);
if (stack.isFluidEqual(resource)) { if (FluidStack.isSameFluidSameComponents(stack, resource)) {
int remain = stack.getAmount(); int remain = stack.getAmount();
int drain = Math.min(to_drain, remain); int drain = Math.min(to_drain, remain);
drained += drain; drained += drain;
@@ -155,7 +156,7 @@ public class BaseTank implements IFluidHandler, AliasCollection<FluidStack> {
int drained = 0; int drained = 0;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
FluidStack stack = list.get(i); FluidStack stack = list.get(i);
if (!stack.isEmpty() && (ans == null || stack.isFluidEqual(ans))) { if (!stack.isEmpty() && (ans == null || FluidStack.isSameFluidSameComponents(stack, ans))) {
int remain = stack.getAmount(); int remain = stack.getAmount();
int drain = Math.min(to_drain, remain); int drain = Math.min(to_drain, remain);
drained += drain; drained += drain;

View File

@@ -3,7 +3,7 @@ package dev.xkmc.l2core.base.tile;
import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Pair;
import net.neoforged.neoforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.FluidStack;
import net.neoforged.neoforge.fluids.capability.IFluidHandler; import net.neoforged.neoforge.fluids.capability.IFluidHandler;
import net.neoforged.neoforge.items.wrapper.EmptyHandler; import net.neoforged.neoforge.fluids.capability.templates.EmptyFluidHandler;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -85,36 +85,31 @@ public class CombinedTankWrapper implements IFluidHandler {
} }
@Override @Override
public int fill(FluidStack resource, FluidAction action) { public int fill(FluidStack input, FluidAction action) {
if (resource.isEmpty()) if (input.isEmpty())
return 0; return 0;
int filled = 0; int ans = 0;
resource = resource.copy(); input = input.copy();
boolean found = false;
boolean fittingHandlerFound = false;
Outer:
for (boolean searchPass : new boolean[]{true, false}) { for (boolean searchPass : new boolean[]{true, false}) {
for (IFluidHandler iFluidHandler : fillable()) { for (IFluidHandler handler : fillable()) {
for (int i = 0; i < handler.getTanks(); i++)
for (int i = 0; i < iFluidHandler.getTanks(); i++) if (searchPass && FluidStack.isSameFluidSameComponents(handler.getFluidInTank(i), input))
if (searchPass && iFluidHandler.getFluidInTank(i) found = true;
.isFluidEqual(resource)) if (searchPass && !found)
fittingHandlerFound = true;
if (searchPass && !fittingHandlerFound)
continue; continue;
int filler = handler.fill(input, action);
int filledIntoCurrent = iFluidHandler.fill(resource, action); input.shrink(filler);
resource.shrink(filledIntoCurrent); ans += filler;
filled += filledIntoCurrent; if (input.isEmpty() || found || enforceVariety && filler != 0)
return ans;
if (resource.isEmpty() || fittingHandlerFound || enforceVariety && filledIntoCurrent != 0)
break Outer;
} }
} }
return filled; return ans;
} }
@Override @Override
@@ -122,41 +117,41 @@ public class CombinedTankWrapper implements IFluidHandler {
if (resource.isEmpty()) if (resource.isEmpty())
return resource; return resource;
FluidStack drained = FluidStack.EMPTY; FluidStack ans = FluidStack.EMPTY;
resource = resource.copy(); resource = resource.copy();
for (IFluidHandler iFluidHandler : drainable()) { for (IFluidHandler handler : drainable()) {
FluidStack drainedFromCurrent = iFluidHandler.drain(resource, action); FluidStack drained = handler.drain(resource, action);
int amount = drainedFromCurrent.getAmount(); int amount = drained.getAmount();
resource.shrink(amount); resource.shrink(amount);
if (!drainedFromCurrent.isEmpty() && (drained.isEmpty() || drainedFromCurrent.isFluidEqual(drained))) if (!drained.isEmpty() && (ans.isEmpty() || FluidStack.isSameFluidSameComponents(drained, ans)))
drained = new FluidStack(drainedFromCurrent.getFluid(), amount + drained.getAmount(), ans = new FluidStack(drained.getFluidHolder(), amount + ans.getAmount(),
drainedFromCurrent.getTag()); drained.getComponentsPatch());
if (resource.isEmpty()) if (resource.isEmpty())
break; break;
} }
return drained; return ans;
} }
@Override @Override
public FluidStack drain(int maxDrain, FluidAction action) { public FluidStack drain(int maxDrain, FluidAction action) {
FluidStack drained = FluidStack.EMPTY; FluidStack ans = FluidStack.EMPTY;
for (IFluidHandler iFluidHandler : drainable()) { for (IFluidHandler iFluidHandler : drainable()) {
FluidStack drainedFromCurrent = iFluidHandler.drain(maxDrain, action); FluidStack drained = iFluidHandler.drain(maxDrain, action);
int amount = drainedFromCurrent.getAmount(); int amount = drained.getAmount();
maxDrain -= amount; maxDrain -= amount;
if (!drainedFromCurrent.isEmpty() && (drained.isEmpty() || drainedFromCurrent.isFluidEqual(drained))) if (!drained.isEmpty() && (ans.isEmpty() || FluidStack.isSameFluidSameComponents(drained, ans)))
drained = new FluidStack(drainedFromCurrent.getFluid(), amount + drained.getAmount(), ans = new FluidStack(drained.getFluidHolder(), amount + ans.getAmount(),
drainedFromCurrent.getTag()); drained.getComponentsPatch());
if (maxDrain == 0) if (maxDrain == 0)
break; break;
} }
return drained; return ans;
} }
protected int getIndexForSlot(int slot) { protected int getIndexForSlot(int slot) {
@@ -170,7 +165,7 @@ public class CombinedTankWrapper implements IFluidHandler {
protected IFluidHandler getHandlerFromIndex(int index) { protected IFluidHandler getHandlerFromIndex(int index) {
if (index < 0 || index >= list.size()) if (index < 0 || index >= list.size())
return (IFluidHandler) EmptyHandler.INSTANCE; return EmptyFluidHandler.INSTANCE;
return list.get(index).getFirst(); return list.get(index).getFirst();
} }

View File

@@ -0,0 +1,49 @@
package dev.xkmc.l2core.capability.conditionals;
import dev.xkmc.l2core.capability.player.PlayerCapabilityTemplate;
import dev.xkmc.l2core.init.L2LibReg;
import dev.xkmc.l2serial.serialization.marker.SerialClass;
import dev.xkmc.l2serial.serialization.marker.SerialField;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import java.util.TreeSet;
@SerialClass
public class PlayerFlagData extends PlayerCapabilityTemplate<PlayerFlagData> {
public static void addFlag(LivingEntity entity, String str) {
if (entity instanceof Player player) {
L2LibReg.FLAGS.type().get(player).addFlag(str);
if (player instanceof ServerPlayer sp)
L2LibReg.FLAGS.type().network.toClient(sp);
} else {
entity.addTag(str);
}
}
public static boolean hasFlag(LivingEntity entity, String str) {
if (entity instanceof Player player) {
return L2LibReg.FLAGS.type().get(player).hasFlag(str);
} else {
return entity.getTags().contains(str);
}
}
@SerialField
private final TreeSet<String> flags = new TreeSet<>();
public void addFlag(String str) {
flags.add(str);
}
public boolean hasFlag(String flag) {
return flags.contains(flag);
}
public static void register() {
}
}

View File

@@ -9,7 +9,7 @@ public record TokenKey<T extends ConditionalToken>(String type, String id) {
} }
public ResourceLocation asLocation() { public ResourceLocation asLocation() {
return new ResourceLocation(type, id); return ResourceLocation.fromNamespaceAndPath(type, id);
} }
} }

View File

@@ -1,7 +1,8 @@
package dev.xkmc.l2core.capability.level; package dev.xkmc.l2core.capability.level;
import dev.xkmc.l2serial.serialization.SerialClass;
import dev.xkmc.l2serial.serialization.codec.TagCodec; import dev.xkmc.l2serial.serialization.codec.TagCodec;
import dev.xkmc.l2serial.serialization.marker.SerialClass;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.saveddata.SavedData; import net.minecraft.world.level.saveddata.SavedData;
@@ -9,8 +10,8 @@ import net.minecraft.world.level.saveddata.SavedData;
public class BaseSavedData extends SavedData { public class BaseSavedData extends SavedData {
@Override @Override
public CompoundTag save(CompoundTag tag) { public CompoundTag save(CompoundTag tag, HolderLookup.Provider provider) {
TagCodec.toTag(tag, this); new TagCodec(provider).toTag(tag, this);
return tag; return tag;
} }
@@ -20,5 +21,4 @@ public class BaseSavedData extends SavedData {
} }
} }

View File

@@ -1,11 +0,0 @@
package dev.xkmc.l2core.compat.curios;
import net.minecraft.resources.ResourceLocation;
import java.util.ArrayList;
public record CurioEntityBuilder(
ArrayList<ResourceLocation> entities,
ArrayList<String> slots,
ArrayList<SlotCondition> conditions) {
}

View File

@@ -1,28 +0,0 @@
package dev.xkmc.l2core.compat.curios;
import java.util.ArrayList;
import static dev.xkmc.l2core.compat.curios.CurioSlotBuilder.Operation.SET;
public record CurioSlotBuilder(int order, String icon, int size,
Operation operation,
boolean add_cosmetic,
boolean use_native_gui,
boolean render_toggle,
boolean replace, ArrayList<SlotCondition> conditions) {
public CurioSlotBuilder(int order, String icon) {
this(order, icon, 1, SET);
}
public CurioSlotBuilder(int order, String icon, int size,
Operation operation) {
this(order, icon, size, operation,
false, true, true, false, SlotCondition.of());
}
public enum Operation {
SET, ADD, REMOVE
}
}

View File

@@ -1,19 +0,0 @@
package dev.xkmc.l2core.compat.curios;
import java.util.ArrayList;
public record SlotCondition(String type, String modid) {
public static ArrayList<SlotCondition> of(String... ids) {
ArrayList<SlotCondition> ans = new ArrayList<>();
for (String id : ids) {
ans.add(new SlotCondition(id));
}
return ans;
}
public SlotCondition(String modid) {
this("forge:mod_loaded", modid);
}
}

View File

@@ -1,8 +0,0 @@
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
package dev.xkmc.l2core.compat.curios;
import net.minecraft.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@@ -1,4 +1,4 @@
package dev.xkmc.l2core.init.events; package dev.xkmc.l2core.events;
import dev.xkmc.l2core.capability.attachment.GeneralCapabilityHolder; import dev.xkmc.l2core.capability.attachment.GeneralCapabilityHolder;
import dev.xkmc.l2core.capability.player.PlayerCapabilityHolder; import dev.xkmc.l2core.capability.player.PlayerCapabilityHolder;

View File

@@ -1,4 +1,4 @@
package dev.xkmc.l2core.init.events; package dev.xkmc.l2core.events;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;

View File

@@ -1,6 +1,5 @@
package dev.xkmc.l2core.init.events; package dev.xkmc.l2core.events;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexConsumer;
@@ -26,18 +25,15 @@ import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.client.event.ClientTickEvent; import net.neoforged.neoforge.client.event.ClientTickEvent;
import net.neoforged.neoforge.client.event.RenderLevelStageEvent; import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
import net.neoforged.neoforge.client.event.RenderLivingEvent; import net.neoforged.neoforge.client.event.RenderLivingEvent;
import net.neoforged.neoforge.event.TickEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -81,11 +77,11 @@ public class ClientEffectRenderEvents {
public static void onLivingEntityRender(RenderLivingEvent.Post<?, ?> event) { public static void onLivingEntityRender(RenderLivingEvent.Post<?, ?> event) {
LivingEntity entity = event.getEntity(); LivingEntity entity = event.getEntity();
if (!L2LibReg.EFFECT.type().isProper(entity)) return; if (!L2LibReg.EFFECT.type().isProper(entity)) return;
if (entity.getTags().contains("ClientOnly")) return; if (entity.getTags().contains("ClientOnly")) return;//TODO
ClientEffectCap cap = L2LibReg.EFFECT.type().get(entity); ClientEffectCap cap = L2LibReg.EFFECT.type().get(entity);
List<Pair<ClientRenderEffect, Integer>> l0 = new ArrayList<>(); List<Pair<ClientRenderEffect, Integer>> l0 = new ArrayList<>();
for (Map.Entry<MobEffect, Integer> entry : cap.map.entrySet()) { for (var entry : cap.map.entrySet()) {
if (entry.getKey() instanceof ClientRenderEffect effect) { if (entry.getKey().value() instanceof ClientRenderEffect effect) {
l0.add(Pair.of(effect, entry.getValue())); l0.add(Pair.of(effect, entry.getValue()));
} }
} }
@@ -103,7 +99,6 @@ public class ClientEffectRenderEvents {
} }
} }
int n = index; int n = index;
int w = (int) Math.ceil(Math.sqrt(n)); int w = (int) Math.ceil(Math.sqrt(n));
int h = (int) Math.ceil(n * 1d / w); int h = (int) Math.ceil(n * 1d / w);
@@ -155,10 +150,9 @@ public class ClientEffectRenderEvents {
} }
private static void iconVertex(PoseStack.Pose entry, VertexConsumer builder, float x, float y, float u, float v) { private static void iconVertex(PoseStack.Pose entry, VertexConsumer builder, float x, float y, float u, float v) {
builder.vertex(entry.pose(), x, y, 0) builder.addVertex(entry.pose(), x, y, 0)
.uv(u, v) .setUv(u, v)
.normal(entry.normal(), 0.0F, 1.0F, 0.0F) .setNormal(entry, 0.0F, 1.0F, 0.0F);
.endVertex();
} }
public static RenderType get2DIcon(ResourceLocation rl) { public static RenderType get2DIcon(ResourceLocation rl) {
@@ -188,5 +182,4 @@ public class ClientEffectRenderEvents {
} }
} }
} }

View File

@@ -1,26 +1,30 @@
package dev.xkmc.l2core.init.events; package dev.xkmc.l2core.events;
import dev.xkmc.l2core.base.effects.EffectToClient; import dev.xkmc.l2core.base.effects.EffectToClient;
import dev.xkmc.l2core.init.L2Core; import dev.xkmc.l2core.init.L2Core;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.Registries;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.TagKey;
import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.Mod; import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.event.entity.living.MobEffectEvent; import net.neoforged.neoforge.event.entity.living.MobEffectEvent;
import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.entity.player.PlayerEvent;
import java.util.HashSet; @EventBusSubscriber(modid = L2Core.MODID, bus = EventBusSubscriber.Bus.GAME)
import java.util.Set;
@Mod.EventBusSubscriber(modid = L2Core.MODID, bus = Mod.EventBusSubscriber.Bus.FORGE)
public class EffectSyncEvents { public class EffectSyncEvents {
public static final Set<MobEffect> TRACKED = new HashSet<>(); public static final TagKey<MobEffect> SYNCED = TagKey.create(Registries.MOB_EFFECT, L2Core.loc("synced"));
private static boolean isTracked(Holder<MobEffect> eff) {
return eff.is(SYNCED);
}
@SubscribeEvent @SubscribeEvent
public static void onPotionAddedEvent(MobEffectEvent.Added event) { public static void onPotionAddedEvent(MobEffectEvent.Added event) {
if (TRACKED.contains(event.getEffectInstance().getEffect())) { if (isTracked(event.getEffectInstance().getEffect())) {
onEffectAppear(event.getEffectInstance().getEffect(), event.getEntity(), event.getEffectInstance().getAmplifier()); onEffectAppear(event.getEffectInstance().getEffect(), event.getEntity(), event.getEffectInstance().getAmplifier());
} }
} }
@@ -28,7 +32,7 @@ public class EffectSyncEvents {
@SubscribeEvent @SubscribeEvent
public static void onPotionRemoveEvent(MobEffectEvent.Remove event) { public static void onPotionRemoveEvent(MobEffectEvent.Remove event) {
if (event.getEffectInstance() != null && TRACKED.contains(event.getEffectInstance().getEffect())) { if (event.getEffectInstance() != null && isTracked(event.getEffectInstance().getEffect())) {
onEffectDisappear(event.getEffectInstance().getEffect(), event.getEntity()); onEffectDisappear(event.getEffectInstance().getEffect(), event.getEntity());
} }
} }
@@ -36,17 +40,16 @@ public class EffectSyncEvents {
@SubscribeEvent @SubscribeEvent
public static void onPotionExpiryEvent(MobEffectEvent.Expired event) { public static void onPotionExpiryEvent(MobEffectEvent.Expired event) {
if (event.getEffectInstance() != null && TRACKED.contains(event.getEffectInstance().getEffect())) { if (event.getEffectInstance() != null && isTracked(event.getEffectInstance().getEffect())) {
onEffectDisappear(event.getEffectInstance().getEffect(), event.getEntity()); onEffectDisappear(event.getEffectInstance().getEffect(), event.getEntity());
} }
} }
@SubscribeEvent @SubscribeEvent
public static void onPlayerStartTracking(PlayerEvent.StartTracking event) { public static void onPlayerStartTracking(PlayerEvent.StartTracking event) {
if (!(event.getTarget() instanceof LivingEntity le)) if (!(event.getTarget() instanceof LivingEntity le)) return;
return; for (var eff : le.getActiveEffectsMap().keySet()) {
for (MobEffect eff : le.getActiveEffectsMap().keySet()) { if (isTracked(eff)) {
if (TRACKED.contains(eff)) {
onEffectAppear(eff, le, le.getActiveEffectsMap().get(eff).getAmplifier()); onEffectAppear(eff, le, le.getActiveEffectsMap().get(eff).getAmplifier());
} }
} }
@@ -54,10 +57,9 @@ public class EffectSyncEvents {
@SubscribeEvent @SubscribeEvent
public static void onPlayerStopTracking(PlayerEvent.StopTracking event) { public static void onPlayerStopTracking(PlayerEvent.StopTracking event) {
if (!(event.getTarget() instanceof LivingEntity le)) if (!(event.getTarget() instanceof LivingEntity le)) return;
return; for (var eff : le.getActiveEffectsMap().keySet()) {
for (MobEffect eff : le.getActiveEffectsMap().keySet()) { if (isTracked(eff)) {
if (TRACKED.contains(eff)) {
onEffectDisappear(eff, le); onEffectDisappear(eff, le);
} }
} }
@@ -66,11 +68,10 @@ public class EffectSyncEvents {
@SubscribeEvent @SubscribeEvent
public static void onServerPlayerJoin(PlayerEvent.PlayerLoggedInEvent event) { public static void onServerPlayerJoin(PlayerEvent.PlayerLoggedInEvent event) {
ServerPlayer e = (ServerPlayer) event.getEntity(); ServerPlayer e = (ServerPlayer) event.getEntity();
if (e != null) { if (e == null) return;
for (MobEffect eff : e.getActiveEffectsMap().keySet()) { for (var eff : e.getActiveEffectsMap().keySet()) {
if (TRACKED.contains(eff)) { if (isTracked(eff)) {
onEffectAppear(eff, e, e.getActiveEffectsMap().get(eff).getAmplifier()); onEffectAppear(eff, e, e.getActiveEffectsMap().get(eff).getAmplifier());
}
} }
} }
} }
@@ -78,21 +79,20 @@ public class EffectSyncEvents {
@SubscribeEvent @SubscribeEvent
public static void onServerPlayerLeave(PlayerEvent.PlayerLoggedOutEvent event) { public static void onServerPlayerLeave(PlayerEvent.PlayerLoggedOutEvent event) {
ServerPlayer e = (ServerPlayer) event.getEntity(); ServerPlayer e = (ServerPlayer) event.getEntity();
if (e != null) { if (e == null) return;
for (MobEffect eff : e.getActiveEffectsMap().keySet()) { for (var eff : e.getActiveEffectsMap().keySet()) {
if (TRACKED.contains(eff)) { if (isTracked(eff)) {
onEffectDisappear(eff, e); onEffectDisappear(eff, e);
}
} }
} }
} }
private static void onEffectAppear(MobEffect eff, LivingEntity e, int lv) { private static void onEffectAppear(Holder<MobEffect> eff, LivingEntity e, int lv) {
if (e.level().isClientSide()) return; if (e.level().isClientSide()) return;
L2Core.PACKET_HANDLER.toTrackingPlayers(new EffectToClient(e.getId(), eff, true, lv), e); L2Core.PACKET_HANDLER.toTrackingPlayers(new EffectToClient(e.getId(), eff, true, lv), e);
} }
private static void onEffectDisappear(MobEffect eff, LivingEntity e) { private static void onEffectDisappear(Holder<MobEffect> eff, LivingEntity e) {
if (e.level().isClientSide()) return; if (e.level().isClientSide()) return;
L2Core.PACKET_HANDLER.toTrackingPlayers(new EffectToClient(e.getId(), eff, false, 0), e); L2Core.PACKET_HANDLER.toTrackingPlayers(new EffectToClient(e.getId(), eff, false, 0), e);
} }

View File

@@ -0,0 +1,43 @@
package dev.xkmc.l2core.events;
import dev.xkmc.l2core.init.L2Core;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.event.tick.ServerTickEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BooleanSupplier;
@EventBusSubscriber(modid = L2Core.MODID, bus = EventBusSubscriber.Bus.GAME)
public class SchedulerHandler {
@SubscribeEvent
public static void serverTick(ServerTickEvent.Post event) {
execute();
}
private static List<BooleanSupplier> TASKS = new ArrayList<>();
public static synchronized void schedule(Runnable runnable) {
TASKS.add(() -> {
runnable.run();
return true;
});
}
public static synchronized void schedulePersistent(BooleanSupplier runnable) {
TASKS.add(runnable);
}
private static synchronized void execute() {
if (TASKS.isEmpty()) return;
var temp = TASKS;
TASKS = new ArrayList<>();
temp.removeIf(BooleanSupplier::getAsBoolean);
temp.addAll(TASKS);
TASKS = temp;
}
}

View File

@@ -1,7 +1,7 @@
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
package dev.xkmc.l2core.util; package dev.xkmc.l2core.events;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;

View File

@@ -3,9 +3,9 @@ package dev.xkmc.l2core.init;
import dev.xkmc.l2core.base.effects.EffectToClient; import dev.xkmc.l2core.base.effects.EffectToClient;
import dev.xkmc.l2core.capability.conditionals.TokenToClient; import dev.xkmc.l2core.capability.conditionals.TokenToClient;
import dev.xkmc.l2core.capability.player.PlayerCapToClient; import dev.xkmc.l2core.capability.player.PlayerCapToClient;
import dev.xkmc.l2core.serial.config.SyncPacket;
import dev.xkmc.l2serial.network.PacketHandler; import dev.xkmc.l2serial.network.PacketHandler;
import dev.xkmc.l2serial.serialization.custom_handler.Handlers; import dev.xkmc.l2serial.serialization.custom_handler.Handlers;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.IEventBus;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
@@ -35,6 +35,7 @@ public class L2Core {
public L2Core(IEventBus bus) { public L2Core(IEventBus bus) {
Handlers.register(); Handlers.register();
L2LibReg.register(bus); L2LibReg.register(bus);
} }
@SubscribeEvent @SubscribeEvent
@@ -42,4 +43,8 @@ public class L2Core {
PACKET_HANDLER.register(event); PACKET_HANDLER.register(event);
} }
public static ResourceLocation loc(String id) {
return ResourceLocation.fromNamespaceAndPath(MODID, id);
}
} }

View File

@@ -3,12 +3,12 @@ package dev.xkmc.l2core.init;
import dev.xkmc.l2core.base.effects.ClientEffectCap; import dev.xkmc.l2core.base.effects.ClientEffectCap;
import dev.xkmc.l2core.base.menu.base.MenuLayoutConfig; import dev.xkmc.l2core.base.menu.base.MenuLayoutConfig;
import dev.xkmc.l2core.capability.conditionals.ConditionalData; import dev.xkmc.l2core.capability.conditionals.ConditionalData;
import dev.xkmc.l2core.capability.conditionals.PlayerFlagData;
import dev.xkmc.l2core.capability.player.PlayerCapabilityNetworkHandler; import dev.xkmc.l2core.capability.player.PlayerCapabilityNetworkHandler;
import dev.xkmc.l2core.init.reg.datapack.DatapackReg; import dev.xkmc.l2core.init.reg.datapack.DatapackReg;
import dev.xkmc.l2core.init.reg.simple.*; import dev.xkmc.l2core.init.reg.simple.*;
import dev.xkmc.l2core.serial.conditions.*; import dev.xkmc.l2core.serial.conditions.*;
import dev.xkmc.l2core.serial.ingredients.EnchantmentIngredient; import dev.xkmc.l2core.serial.ingredients.EnchantmentIngredient;
import dev.xkmc.l2core.serial.ingredients.MobEffectIngredient;
import dev.xkmc.l2core.serial.ingredients.PotionIngredient; import dev.xkmc.l2core.serial.ingredients.PotionIngredient;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.IEventBus;
@@ -23,7 +23,6 @@ public class L2LibReg {
public static final IngReg INGREDIENT = IngReg.of(REG); public static final IngReg INGREDIENT = IngReg.of(REG);
public static final IngVal<EnchantmentIngredient> ING_ENCH = INGREDIENT.reg("enchantment", EnchantmentIngredient.class); public static final IngVal<EnchantmentIngredient> ING_ENCH = INGREDIENT.reg("enchantment", EnchantmentIngredient.class);
public static final IngVal<PotionIngredient> ING_POTION = INGREDIENT.reg("potion", PotionIngredient.class); public static final IngVal<PotionIngredient> ING_POTION = INGREDIENT.reg("potion", PotionIngredient.class);
public static final IngVal<MobEffectIngredient> ING_EFF = INGREDIENT.reg("mob_effect", MobEffectIngredient.class);
// conditions // conditions
public static final CdcReg<ICondition> CONDITION = CdcReg.of(REG, NeoForgeRegistries.CONDITION_SERIALIZERS); public static final CdcReg<ICondition> CONDITION = CdcReg.of(REG, NeoForgeRegistries.CONDITION_SERIALIZERS);
@@ -35,10 +34,13 @@ public class L2LibReg {
// attachments // attachments
public static final AttReg ATTACHMENT = AttReg.of(REG); public static final AttReg ATTACHMENT = AttReg.of(REG);
public static final AttVal.CapVal<LivingEntity, ClientEffectCap> EFFECT = ATTACHMENT.entity("effect", public static final AttVal.CapVal<LivingEntity, ClientEffectCap> EFFECT = ATTACHMENT.entity("effect",
ClientEffectCap.class, ClientEffectCap::new, LivingEntity.class, e -> e.level().isClientSide()); ClientEffectCap.class, ClientEffectCap::new, LivingEntity.class, e -> e.level().isClientSide());
public static final AttVal.PlayerVal<ConditionalData> CONDITIONAL = ATTACHMENT.player("conditionals", public static final AttVal.PlayerVal<ConditionalData> CONDITIONAL = ATTACHMENT.player("conditionals",
ConditionalData.class, ConditionalData::new, PlayerCapabilityNetworkHandler::new); ConditionalData.class, ConditionalData::new, PlayerCapabilityNetworkHandler::new);
public static final AttVal.PlayerVal<PlayerFlagData> FLAGS = ATTACHMENT.player("flags",
PlayerFlagData.class, PlayerFlagData::new, PlayerCapabilityNetworkHandler::new);
public static final DatapackReg<MenuLayoutConfig> MENU_LAYOUT = REG.dataReg("menu_layout", MenuLayoutConfig.class); public static final DatapackReg<MenuLayoutConfig> MENU_LAYOUT = REG.dataReg("menu_layout", MenuLayoutConfig.class);

View File

@@ -1,21 +0,0 @@
package dev.xkmc.l2core.init.events;
import dev.xkmc.l2core.init.L2Core;
import dev.xkmc.l2core.util.raytrace.EntityTarget;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.event.TickEvent;
@Mod.EventBusSubscriber(value = Dist.CLIENT, modid = L2Core.MODID, bus = Mod.EventBusSubscriber.Bus.FORGE)
public class ClientGeneralEventHandler {
@SubscribeEvent
public static void clientTick(TickEvent.ClientTickEvent event) {
if (event.phase != TickEvent.Phase.END) return;
for (EntityTarget target : EntityTarget.LIST) {
target.tickRender();
}
}
}

View File

@@ -1,67 +0,0 @@
package dev.xkmc.l2core.init.events;
import dev.xkmc.l2core.base.explosion.BaseExplosion;
import dev.xkmc.l2core.init.L2Core;
import dev.xkmc.l2core.serial.config.PacketHandlerWithConfig;
import dev.xkmc.l2core.util.raytrace.RayTraceUtil;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.event.AddReloadListenerEvent;
import net.neoforged.neoforge.event.OnDatapackSyncEvent;
import net.neoforged.neoforge.event.TickEvent;
import net.neoforged.neoforge.event.level.ExplosionEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BooleanSupplier;
@Mod.EventBusSubscriber(modid = L2Core.MODID, bus = Mod.EventBusSubscriber.Bus.FORGE)
public class GeneralEventHandler {
@SubscribeEvent
public static void addReloadListeners(AddReloadListenerEvent event) {
PacketHandlerWithConfig.addReloadListeners(event);
}
@SubscribeEvent
public static void onDatapackSync(OnDatapackSyncEvent event) {
PacketHandlerWithConfig.onDatapackSync(event);
}
@SubscribeEvent
public static void serverTick(TickEvent.ServerTickEvent event) {
if (event.phase != TickEvent.Phase.END) return;
RayTraceUtil.serverTick();
execute();
}
@SubscribeEvent
public static void onDetonate(ExplosionEvent.Detonate event) {
if (event.getExplosion() instanceof BaseExplosion exp) {
event.getAffectedEntities().removeIf(e -> !exp.hurtEntity(e));
}
}
private static List<BooleanSupplier> TASKS = new ArrayList<>();
public static synchronized void schedule(Runnable runnable) {
TASKS.add(() -> {
runnable.run();
return true;
});
}
public static synchronized void schedulePersistent(BooleanSupplier runnable) {
TASKS.add(runnable);
}
private static synchronized void execute() {
if (TASKS.isEmpty()) return;
var temp = TASKS;
TASKS = new ArrayList<>();
temp.removeIf(BooleanSupplier::getAsBoolean);
temp.addAll(TASKS);
TASKS = temp;
}
}

View File

@@ -1,8 +0,0 @@
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
package dev.xkmc.l2core.init.events;
import net.minecraft.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@@ -1,166 +0,0 @@
package dev.xkmc.l2core.init.reg.registrate;
/*TODO
public class L2Registrate extends AbstractRegistrate<L2Registrate> {
public L2Registrate(String modid) {
super(modid);
registerEventListeners(FMLJavaModLoadingContext.get().getModEventBus());
}
public <T extends NamedEntry<T>, P extends T> GenericBuilder<T, P> generic(RegistryInstance<T> cls, String id, NonNullSupplier<P> sup) {
return entry(id, cb -> new GenericBuilder<>(this, id, cb, cls.key(), sup));
}
public <T extends Recipe<?>> RegistryEntry<RecipeType<T>> recipe(String id) {
return simple(id, ForgeRegistries.Keys.RECIPE_TYPES, () -> new RecipeType<>() {
});
}
@Deprecated
@Override
public <T extends Enchantment> EnchantmentBuilder<T, L2Registrate> enchantment(String name, EnchantmentCategory type, EnchantmentBuilder.EnchantmentFactory<T> factory) {
return super.enchantment(name, type, factory);
}
public <T extends Enchantment> EnchantmentBuilder<T, L2Registrate> enchantment(String name, EnchantmentCategory type, EnchantmentBuilder.EnchantmentFactory<T> factory, String desc) {
addRawLang("enchantment." + getModid() + "." + name + ".desc", desc);
return super.enchantment(name, type, factory);
}
public <T extends MobEffect> NoConfigBuilder<MobEffect, T, L2Registrate> effect(String name, NonNullSupplier<T> sup, String desc) {
addRawLang("effect." + getModid() + "." + name + ".description", desc);
return entry(name, cb -> new NoConfigBuilder<>(this, this, name, cb, ForgeRegistries.Keys.MOB_EFFECTS, sup));
}
@SuppressWarnings({"unchecked", "unsafe"})
public <E extends NamedEntry<E>> RegistryInstance<E> newRegistry(String id, Class<?> cls, Consumer<RegistryBuilder<E>> cons) {
ResourceKey<Registry<E>> key = makeRegistry(id, () -> {
var ans = new RegistryBuilder<E>();
ans.onCreate((r, s) -> new RLClassHandler<>((Class<E>) cls, () -> r));
cons.accept(ans);
return ans;
});
return new RegistryInstance<>(Suppliers.memoize(() -> RegistryManager.ACTIVE.getRegistry(key)), key);
}
public <E extends NamedEntry<E>> RegistryInstance<E> newRegistry(String id, Class<?> cls) {
return newRegistry(id, cls, e -> {
});
}
public synchronized RegistryEntry<CreativeModeTab> buildModCreativeTab(String name, String def, Consumer<CreativeModeTab.Builder> config) {
ResourceLocation id = new ResourceLocation(getModid(), name);
defaultCreativeTab(ResourceKey.create(Registries.CREATIVE_MODE_TAB, id));
return buildCreativeTabImpl(name, this.addLang("itemGroup", id, def), config);
}
public synchronized RegistryEntry<CreativeModeTab> buildL2CreativeTab(String name, String def, Consumer<CreativeModeTab.Builder> config) {
ResourceLocation id = new ResourceLocation(L2Library.MODID, name);
defaultCreativeTab(ResourceKey.create(Registries.CREATIVE_MODE_TAB, id));
TabSorter sorter = new TabSorter(getModid() + ":" + name, id);
return L2Library.REGISTRATE.buildCreativeTabImpl(name, this.addLang("itemGroup", id, def), b -> {
config.accept(b);
sorter.sort(b);
});
}
private synchronized RegistryEntry<CreativeModeTab> buildCreativeTabImpl(String name, Component comp, Consumer<CreativeModeTab.Builder> config) {
return this.generic(self(), name, Registries.CREATIVE_MODE_TAB, () -> {
var builder = CreativeModeTab.builder().title(comp)
.withTabsBefore(CreativeModeTabs.SPAWN_EGGS);
config.accept(builder);
return builder.build();
}).register();
}
public record RegistryInstance<E extends NamedEntry<E>>(Supplier<IForgeRegistry<E>> supplier,
ResourceKey<Registry<E>> key) implements Supplier<IForgeRegistry<E>> {
@Override
public IForgeRegistry<E> get() {
return supplier().get();
}
}
public static class GenericBuilder<T extends NamedEntry<T>, P extends T> extends AbstractBuilder<T, P, L2Registrate, GenericBuilder<T, P>> {
private final NonNullSupplier<P> sup;
GenericBuilder(L2Registrate parent, String name, BuilderCallback callback, ResourceKey<Registry<T>> registryType, NonNullSupplier<P> sup) {
super(parent, parent, name, callback, registryType);
this.sup = sup;
}
@Override
protected @NonnullType @NotNull P createEntry() {
return sup.get();
}
public GenericBuilder<T, P> defaultLang() {
return lang(NamedEntry::getDescriptionId, RegistrateLangProvider.toEnglishName(this.getName()));
}
}
private static class TabSorter {
private static final TreeMap<String, TabSorter> MAP = new TreeMap<>();
private static final HashSet<ResourceLocation> SET = new HashSet<>();
private final ResourceLocation id;
private TabSorter(String str, ResourceLocation id) {
MAP.put(str, this);
SET.add(id);
this.id = id;
}
public void sort(CreativeModeTab.Builder b) {
var list = new ArrayList<>(MAP.values());
boolean after = false;
ResourceLocation before = null;
for (var e : list) {
if (e == this) {
after = true;
if (before != null) {
b.withTabsBefore(before);
}
continue;
}
if (after) {
b.withTabsAfter(e.id);
return;
} else {
before = e.id;
}
}
for (var e : BuiltInRegistries.CREATIVE_MODE_TAB.entrySet()) {
var id = e.getKey().location();
if (known(id) || known(e.getValue())) {
continue;
}
b.withTabsAfter(id);
}
}
private static boolean known(ResourceLocation id) {
if (id.getNamespace().equals("minecraft")) {
return true;
}
return SET.contains(id);
}
private static boolean known(CreativeModeTab tab) {
for (var other : tab.tabsAfter) {
if (known(other)) {
return true;
}
}
return false;
}
}
}
*/

View File

@@ -1,40 +0,0 @@
package dev.xkmc.l2core.init.reg.registrate;
/*TODO
public class NamedEntry<T extends NamedEntry<T>> {
private final L2Registrate.RegistryInstance<T> registry;
private String desc = null;
public NamedEntry(L2Registrate.RegistryInstance<T> registry) {
this.registry = registry;
}
public @NotNull String getDescriptionId() {
if (desc != null)
return desc;
ResourceLocation rl = getRegistryName();
ResourceLocation reg = registry.get().getRegistryName();
desc = reg.getPath() + "." + rl.getNamespace() + "." + rl.getPath();
return desc;
}
public MutableComponent getDesc() {
return Component.translatable(getDescriptionId());
}
public ResourceLocation getRegistryName() {
return Objects.requireNonNull(registry.get().getKey(getThis()));
}
public String getID() {
return getRegistryName().toString();
}
public T getThis() {
return Wrappers.cast(this);
}
}
*/

View File

@@ -1,8 +0,0 @@
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
package dev.xkmc.l2core.init.reg.registrate;
import net.minecraft.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@@ -24,7 +24,7 @@ public record BooleanValueCondition(String path, ArrayList<String> line, boolean
} }
@Override @Override
public MapCodec<? extends ICondition> codec() { public MapCodec<BooleanValueCondition> codec() {
return L2LibReg.CONDITION_BOOL.get(); return L2LibReg.CONDITION_BOOL.get();
} }

View File

@@ -1,6 +1,6 @@
package dev.xkmc.l2core.serial.conditions; package dev.xkmc.l2core.serial.conditions;
import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec;
import dev.xkmc.l2core.init.L2LibReg; import dev.xkmc.l2core.init.L2LibReg;
import net.neoforged.fml.config.ConfigTracker; import net.neoforged.fml.config.ConfigTracker;
import net.neoforged.neoforge.common.ModConfigSpec; import net.neoforged.neoforge.common.ModConfigSpec;
@@ -24,7 +24,7 @@ public record DoubleValueCondition(String path, ArrayList<String> line, double l
} }
@Override @Override
public Codec<DoubleValueCondition> codec() { public MapCodec<DoubleValueCondition> codec() {
return L2LibReg.CONDITION_DOUBLE.get(); return L2LibReg.CONDITION_DOUBLE.get();
} }

View File

@@ -1,6 +1,6 @@
package dev.xkmc.l2core.serial.conditions; package dev.xkmc.l2core.serial.conditions;
import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec;
import dev.xkmc.l2core.init.L2Core; import dev.xkmc.l2core.init.L2Core;
import dev.xkmc.l2core.init.L2LibReg; import dev.xkmc.l2core.init.L2LibReg;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
@@ -12,8 +12,6 @@ import java.util.ArrayList;
public record IntValueCondition(String path, ArrayList<String> line, int low, int high) implements ICondition { public record IntValueCondition(String path, ArrayList<String> line, int low, int high) implements ICondition {
public static final ResourceLocation ID = new ResourceLocation(L2Core.MODID, "int_config");
public static IntValueCondition of(String file, ModConfigSpec.ConfigValue<Integer> config, int low, int high) { public static IntValueCondition of(String file, ModConfigSpec.ConfigValue<Integer> config, int low, int high) {
return new IntValueCondition(file, new ArrayList<>(config.getPath()), low, high); return new IntValueCondition(file, new ArrayList<>(config.getPath()), low, high);
} }
@@ -29,7 +27,7 @@ public record IntValueCondition(String path, ArrayList<String> line, int low, in
@Override @Override
public Codec<IntValueCondition> codec() { public MapCodec<IntValueCondition> codec() {
return L2LibReg.CONDITION_INT.get(); return L2LibReg.CONDITION_INT.get();
} }

View File

@@ -1,9 +1,7 @@
package dev.xkmc.l2core.serial.conditions; package dev.xkmc.l2core.serial.conditions;
import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec;
import dev.xkmc.l2core.init.L2Core;
import dev.xkmc.l2core.init.L2LibReg; import dev.xkmc.l2core.init.L2LibReg;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.fml.config.ConfigTracker; import net.neoforged.fml.config.ConfigTracker;
import net.neoforged.neoforge.common.ModConfigSpec; import net.neoforged.neoforge.common.ModConfigSpec;
import net.neoforged.neoforge.common.conditions.ICondition; import net.neoforged.neoforge.common.conditions.ICondition;
@@ -13,8 +11,6 @@ import java.util.List;
public record ListStringValueCondition(String path, ArrayList<String> line, String key) implements ICondition { public record ListStringValueCondition(String path, ArrayList<String> line, String key) implements ICondition {
public static final ResourceLocation ID = new ResourceLocation(L2Core.MODID, "string_list_config");
public static ListStringValueCondition of(String file, ModConfigSpec.ConfigValue<List<String>> config, String key) { public static ListStringValueCondition of(String file, ModConfigSpec.ConfigValue<List<String>> config, String key) {
return new ListStringValueCondition(file, new ArrayList<>(config.getPath()), key); return new ListStringValueCondition(file, new ArrayList<>(config.getPath()), key);
} }
@@ -29,7 +25,7 @@ public record ListStringValueCondition(String path, ArrayList<String> line, Stri
} }
@Override @Override
public Codec<ListStringValueCondition> codec() { public MapCodec<ListStringValueCondition> codec() {
return L2LibReg.CONDITION_LIST_STR.get(); return L2LibReg.CONDITION_LIST_STR.get();
} }

View File

@@ -1,9 +1,7 @@
package dev.xkmc.l2core.serial.conditions; package dev.xkmc.l2core.serial.conditions;
import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec;
import dev.xkmc.l2core.init.L2Core;
import dev.xkmc.l2core.init.L2LibReg; import dev.xkmc.l2core.init.L2LibReg;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.fml.config.ConfigTracker; import net.neoforged.fml.config.ConfigTracker;
import net.neoforged.neoforge.common.ModConfigSpec; import net.neoforged.neoforge.common.ModConfigSpec;
import net.neoforged.neoforge.common.conditions.ICondition; import net.neoforged.neoforge.common.conditions.ICondition;
@@ -12,8 +10,6 @@ import java.util.ArrayList;
public record StringValueCondition(String path, ArrayList<String> line, String key) implements ICondition { public record StringValueCondition(String path, ArrayList<String> line, String key) implements ICondition {
public static final ResourceLocation ID = new ResourceLocation(L2Core.MODID, "string_config");
public static StringValueCondition of(String file, ModConfigSpec.ConfigValue<String> config, String key) { public static StringValueCondition of(String file, ModConfigSpec.ConfigValue<String> config, String key) {
return new StringValueCondition(file, new ArrayList<>(config.getPath()), key); return new StringValueCondition(file, new ArrayList<>(config.getPath()), key);
} }
@@ -28,7 +24,7 @@ public record StringValueCondition(String path, ArrayList<String> line, String k
} }
@Override @Override
public Codec<StringValueCondition> codec() { public MapCodec<StringValueCondition> codec() {
return L2LibReg.CONDITION_STR.get(); return L2LibReg.CONDITION_STR.get();
} }

View File

@@ -1,5 +1,6 @@
package dev.xkmc.l2core.serial.recipe; package dev.xkmc.l2core.serial.recipe;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.RegistryAccess; import net.minecraft.core.RegistryAccess;
import net.minecraft.world.Container; import net.minecraft.world.Container;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
@@ -23,13 +24,14 @@ public abstract class BaseRecipe<Rec extends SRec, SRec extends BaseRecipe<?, SR
public abstract boolean matches(Inv inv, Level world); public abstract boolean matches(Inv inv, Level world);
@Override @Override
public abstract ItemStack assemble(Inv inv, RegistryAccess access); public abstract ItemStack assemble(Inv inv, HolderLookup.Provider provider);
@Override
public abstract ItemStack getResultItem(HolderLookup.Provider provider);
@Override @Override
public abstract boolean canCraftInDimensions(int r, int c); public abstract boolean canCraftInDimensions(int r, int c);
public abstract ItemStack getResultItem(RegistryAccess access);
@Override @Override
public final RecipeSerializer<?> getSerializer() { public final RecipeSerializer<?> getSerializer() {
return factory; return factory;

View File

@@ -1,25 +1,23 @@
package dev.xkmc.l2core.util; package dev.xkmc.l2core.util;
import net.minecraft.advancements.critereon.EnchantmentPredicate; import net.minecraft.advancements.critereon.EnchantmentPredicate;
import net.minecraft.advancements.critereon.ItemPredicate;
import net.minecraft.advancements.critereon.MinMaxBounds; import net.minecraft.advancements.critereon.MinMaxBounds;
import net.minecraft.advancements.critereon.StatePropertiesPredicate; import net.minecraft.advancements.critereon.StatePropertiesPredicate;
import net.minecraft.core.Holder;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.enchantment.Enchantment; import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.storage.loot.LootPool; import net.minecraft.world.level.storage.loot.LootPool;
import net.minecraft.world.level.storage.loot.LootTable;
import net.minecraft.world.level.storage.loot.entries.LootItem; import net.minecraft.world.level.storage.loot.entries.LootItem;
import net.minecraft.world.level.storage.loot.entries.LootPoolSingletonContainer; import net.minecraft.world.level.storage.loot.entries.LootPoolSingletonContainer;
import net.minecraft.world.level.storage.loot.functions.ApplyBonusCount;
import net.minecraft.world.level.storage.loot.functions.LootingEnchantFunction;
import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction; import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction;
import net.minecraft.world.level.storage.loot.predicates.*; import net.minecraft.world.level.storage.loot.predicates.LootItemBlockStatePropertyCondition;
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
import net.minecraft.world.level.storage.loot.predicates.LootItemKilledByPlayerCondition;
import net.minecraft.world.level.storage.loot.predicates.LootItemRandomChanceCondition;
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator; import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator;
import net.neoforged.neoforge.common.Tags;
import java.util.Optional; import java.util.Optional;
@@ -40,12 +38,6 @@ public class LootTableTemplate {
.apply(SetItemCountFunction.setCount(UniformGenerator.between(min, max))); .apply(SetItemCountFunction.setCount(UniformGenerator.between(min, max)));
} }
public static LootPoolSingletonContainer.Builder<?> getItem(Item item, int min, int max, int add) {
return LootItem.lootTableItem(item)
.apply(SetItemCountFunction.setCount(UniformGenerator.between(min, max)))
.apply(LootingEnchantFunction.lootingMultiplier(UniformGenerator.between(0, add)));
}
public static LootItemCondition.Builder byPlayer() { public static LootItemCondition.Builder byPlayer() {
return LootItemKilledByPlayerCondition.killedByPlayer(); return LootItemKilledByPlayerCondition.killedByPlayer();
} }
@@ -54,10 +46,6 @@ public class LootTableTemplate {
return LootItemRandomChanceCondition.randomChance(chance); return LootItemRandomChanceCondition.randomChance(chance);
} }
public static LootItemCondition.Builder chance(float chance, float add) {
return LootItemRandomChanceWithLootingCondition.randomChanceAndLootingBoost(chance, add);
}
public static LootItemBlockStatePropertyCondition.Builder withBlockState(Block block, Property<Integer> prop, int low, int high) { public static LootItemBlockStatePropertyCondition.Builder withBlockState(Block block, Property<Integer> prop, int low, int high) {
StatePropertiesPredicate.Builder builder = StatePropertiesPredicate.Builder.properties(); StatePropertiesPredicate.Builder builder = StatePropertiesPredicate.Builder.properties();
builder.matchers.add(new StatePropertiesPredicate.PropertyMatcher(prop.getName(), builder.matchers.add(new StatePropertiesPredicate.PropertyMatcher(prop.getName(),
@@ -85,42 +73,9 @@ public class LootTableTemplate {
); );
} }
public static LootPoolSingletonContainer.Builder<?> cropDrop(Item item) { public static EnchantmentPredicate hasEnchantment(Holder<Enchantment> enchant, int min) {
return LootItem.lootTableItem(item).apply(ApplyBonusCount
.addBonusBinomialDistributionCount(Enchantments.BLOCK_FORTUNE, 0.57f, 3));
}
public static EnchantmentPredicate hasEnchantment(Enchantment enchant, int min) {
return new EnchantmentPredicate(enchant, MinMaxBounds.Ints.atLeast(min)); return new EnchantmentPredicate(enchant, MinMaxBounds.Ints.atLeast(min));
} }
public static LootItemCondition.Builder shearOrSilk(boolean inverted) {
var ans = AnyOfCondition.anyOf(
MatchTool.toolMatches(ItemPredicate.Builder.item().of(Tags.Items.SHEARS)),
MatchTool.toolMatches(ItemPredicate.Builder.item().hasEnchantment(hasEnchantment(Enchantments.SILK_TOUCH, 1)))
);
return inverted ? ans.invert() : ans;
}
public static LootItemCondition.Builder silk(boolean inverted) {
LootItemCondition.Builder ans = MatchTool.toolMatches(ItemPredicate.Builder.item().hasEnchantment(hasEnchantment(Enchantments.SILK_TOUCH, 1)));
return inverted ? InvertedLootItemCondition.invert(ans) : ans;
}
public static LootTable.Builder selfOrOther(Block block, Block base, Item other, int count) {
return LootTable.lootTable()
.withPool(LootTableTemplate.getPool(1, 0)
.add(LootTableTemplate.getItem(base.asItem(), 1))
.when(ExplosionCondition.survivesExplosion())
.when(LootTableTemplate.silk(true)))
.withPool(LootTableTemplate.getPool(1, 0)
.add(LootTableTemplate.getItem(other, count))
.when(ExplosionCondition.survivesExplosion())
.when(LootTableTemplate.silk(true)))
.withPool(LootTableTemplate.getPool(1, 0)
.add(LootTableTemplate.getItem(block.asItem(), 1))
.when(LootTableTemplate.silk(false))
);
}
} }