Compare commits

..

10 Commits

Author SHA1 Message Date
b4e64f7f33 fix: Enchantment Description compatibility 2025-09-02 23:53:53 +08:00
lcy0x1
ea1d87e16d fix token sync 2025-07-28 14:06:49 +08:00
lcy0x1
adfadd5eb7 config fix 2025-03-02 15:44:45 +08:00
lcy0x1
a56299bf56 datagen fix 2025-01-01 15:42:19 +08:00
lcy0x1
d7af5ef4bb prepare for l2h 2024-10-23 09:01:11 +08:00
lcy0x1
21bff77a28 fix proxy 2024-10-05 01:27:25 +08:00
lcy0x1
294fadb7b5 bug fix 2024-09-27 14:14:09 +08:00
lcy0x1
b60e4492cf cuisine 2024-09-27 10:58:21 +08:00
lcy0x1
af889f4808 potion builder 2024-09-12 17:14:46 +08:00
lcy0x1
ca438aac32 force load default 2024-08-28 13:37:46 +08:00
60 changed files with 631 additions and 120 deletions

View File

@@ -1,13 +1,17 @@
plugins { plugins {
id 'java-library' id 'java-library'
id 'eclipse' id 'eclipse'
id 'idea' id 'idea'
id 'maven-publish' id 'maven-publish'
id 'net.neoforged.gradle.userdev' version '7.0.145' id 'net.neoforged.moddev' version '2.0.80'
id 'net.darkhax.curseforgegradle' version '[1.1.24,)'
id "at.stnwtr.gradle-secrets-plugin" version "1.0.1"
id "com.modrinth.minotaur" version "2.+"
} }
version = mod_version version = mod_version
group = 'dev.kxmc' group = 'dev.xkmc'
repositories { repositories {
mavenLocal() mavenLocal()
@@ -17,38 +21,53 @@ base {
archivesName = mod_id archivesName = mod_id
} }
java {
withSourcesJar()
}
java.toolchain.languageVersion = JavaLanguageVersion.of(21) java.toolchain.languageVersion = JavaLanguageVersion.of(21)
minecraft.accessTransformers.file rootProject.file('src/main/resources/META-INF/accesstransformer.cfg') sourceSets {
client {}
server {}
data {}
common {}
}
runs { neoForge {
configureEach { // We currently only support NeoForge versions later than 21.0.x
systemProperty 'forge.logging.markers', 'REGISTRIES' // See https://projects.neoforged.net/neoforged/neoforge for the latest updates
systemProperty 'forge.logging.console.level', 'debug' version = "${neo_version}"
modSource project.sourceSets.main
} // Validate AT files and raise errors when they have invalid targets
// This option is false by default, but turning it on is recommended
//validateAccessTransformers = true
accessTransformers.from "./src/main/resources/META-INF/accesstransformer.cfg"
runs {
client { client {
systemProperty 'forge.enabledGameTestNamespaces', project.mod_id client()
}
server {
systemProperty 'forge.enabledGameTestNamespaces', project.mod_id
programArgument '--nogui'
}
gameTestServer {
systemProperty 'forge.enabledGameTestNamespaces', project.mod_id
} }
data { data {
data()
programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath() programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath()
}
server {
server()
}
}
mods {
"${mod_id}" {
sourceSet sourceSets.main
}
} }
} }
sourceSets.main.resources { srcDir 'src/generated/resources' } sourceSets.main.resources { srcDir 'src/generated/resources' }
dependencies {
implementation "net.neoforged:neoforge:${neo_version}"
}
tasks.withType(ProcessResources).configureEach { tasks.withType(ProcessResources).configureEach {
var replaceProperties = [ var replaceProperties = [
minecraft_version : minecraft_version, minecraft_version_range: minecraft_version_range, minecraft_version : minecraft_version, minecraft_version_range: minecraft_version_range,
@@ -84,10 +103,6 @@ tasks.withType(JavaCompile).configureEach {
if (lljij.toBoolean()) jarJar.enable() if (lljij.toBoolean()) jarJar.enable()
java {
withSourcesJar()
}
jar { jar {
manifest { manifest {
attributes([ attributes([
@@ -148,14 +163,22 @@ dependencies {
implementation "mezz.jei:jei-${jei_minecraft_version}:${jei_version}" implementation "mezz.jei:jei-${jei_minecraft_version}:${jei_version}"
implementation "com.tterrag.registrate:Registrate:${registrate_version}" implementation "com.tterrag.registrate:Registrate:${registrate_version}"
implementation "dev.xkmc:l2serial:${l2serial_ver}" implementation "dev.xkmc:l2serial:${l2serial_ver}"
implementation "vazkii.patchouli:Patchouli:${patchouli_ver}" compileOnly "vazkii.patchouli:Patchouli:${patchouli_ver}"
runtimeOnly "dev.xkmc:l2damagetracker:3.0.2" //runtimeOnly "dev.xkmc:l2damagetracker:3.0.3+2"
runtimeOnly "dev.xkmc:l2menustacker:3.0.9" //runtimeOnly "dev.xkmc:l2menustacker:3.0.9"
runtimeOnly "dev.xkmc:l2itemselector:3.0.7" //runtimeOnly "dev.xkmc:l2itemselector:3.0.8"
runtimeOnly "dev.xkmc:l2library:3.0.2" //runtimeOnly "dev.xkmc:l2library:3.0.2+4"
runtimeOnly "dev.xkmc:l2complements:3.0.2+3" //runtimeOnly "dev.xkmc:l2complements:3.0.2+7"
//runtimeOnly "dev.xkmc:l2archery:3.0.0+8"
//runtimeOnly "curse.maven:embeddium-908741:5630163"
//runtimeOnly "curse.maven:farmers-delight-398521:5566383"
//runtimeOnly "dev.xkmc:cuisinedelight:1.2.2"
//implementation "curse.maven:enchantment-descriptions-250419:5760047"
//implementation "curse.maven:bookshelf-228525:5757624"
//implementation "curse.maven:prickle-1023259:5757615"
runtimeOnly "curse.maven:embeddium-908741:5630163"
} }

View File

@@ -8,9 +8,11 @@ org.gradle.debug=false
neogradle.subsystems.parchment.minecraftVersion=1.20.6 neogradle.subsystems.parchment.minecraftVersion=1.20.6
neogradle.subsystems.parchment.mappingsVersion=2024.06.02 neogradle.subsystems.parchment.mappingsVersion=2024.06.02
org.gradle.configuration-cache=false
minecraft_version=1.21.1 minecraft_version=1.21.1
minecraft_version_range=[1.21.1,1.22) minecraft_version_range=[1.21.1,1.22)
neo_version=21.1.4 neo_version=21.1.143
neo_version_range=[21.1.4,) neo_version_range=[21.1.4,)
loader_version_range=[2,) loader_version_range=[2,)
@@ -18,18 +20,18 @@ loader_version_range=[2,)
mod_id=l2core mod_id=l2core
mod_name=L2Core mod_name=L2Core
mod_license=LGPL-2.1 mod_license=LGPL-2.1
mod_version=3.0.7+31 mod_version=3.0.8+15
mod_group_id=dev.xkmc mod_group_id=dev.xkmc
mod_authors=lcy0x1 mod_authors=lcy0x1
mod_description=Core Library mod for all L2 mods mod_description=Core Library mod for all L2 mods
jei_minecraft_version = 1.21-neoforge jei_minecraft_version = 1.21.1-neoforge
jei_version = 19.5.0.44 jei_version = 19.21.0.246
registrate_version = MC1.21-1.3.0+50 registrate_version = MC1.21-1.3.0+50
patchouli_ver = 1.21-87-NEOFORGE-SNAPSHOT patchouli_ver = 1.21-87-NEOFORGE-SNAPSHOT
lljij = false lljij = false
rootMod = false rootMod = false
l2serial_ver = 3.0.9 l2serial_ver = 3.0.9+4

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
networkTimeout=10000 networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

Binary file not shown.

Binary file not shown.

BIN
libs/l2archery-3.0.0+8.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -7,5 +7,5 @@ pluginManagement {
} }
plugins { plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.5.0' id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0'
} }

View File

@@ -1,4 +1,4 @@
// 1.21 2024-07-25T11:38:15.636395 Registrate Provider for l2core [Registries, Data Maps, Recipes, Advancements, Loot Tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), generic_server_provider, Blockstates, Item models, Lang (en_us/en_ud), generic_client_provider, Tags (mob_effect), Tags (attribute), Tags (enchantment)] // 1.21.1 2025-07-26T01:42:31.138209 Registrate Provider for l2core [Registries, Data Maps, Recipes, Advancements, Loot Tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), generic_server_provider, Blockstates, Item models, Lang (en_us/en_ud), generic_client_provider, Tags (mob_effect), Tags (attribute), Tags (enchantment)]
7fd8a37c6437c7cab27c53dbc0df73ececc1cd44 assets/l2core/lang/en_ud.json 72a986cabe624a799bdb74cc1b5e67dd6f80baed assets/l2core/lang/en_ud.json
18ae34417262501a3c00959390185e01ffb2ae7c assets/l2core/lang/en_us.json 9eab006827655c8a83941f5d9c71681a1244378c assets/l2core/lang/en_us.json
35133e95f1c8fdd7a1c21afcc231fc0bffefb9a8 data/l2core/tags/mob_effect/tracked_effects.json 35133e95f1c8fdd7a1c21afcc231fc0bffefb9a8 data/l2core/tags/mob_effect/tracked_effects.json

View File

@@ -2,7 +2,9 @@
"l2core.configuration.addEnchantmentDescription": "suoıʇdıɹɔsǝᗡ ʇuǝɯʇuɐɥɔuƎ ppⱯ", "l2core.configuration.addEnchantmentDescription": "suoıʇdıɹɔsǝᗡ ʇuǝɯʇuɐɥɔuƎ ppⱯ",
"l2core.configuration.addEnchantmentDescription.tooltip": "SʎⱯMꞀⱯ 'ʎꞀNO‾⟘ℲIHS 'ƎꞀᗺⱯSIᗡ :sǝnןɐΛ pǝʍoןןⱯ", "l2core.configuration.addEnchantmentDescription.tooltip": "SʎⱯMꞀⱯ 'ʎꞀNO‾⟘ℲIHS 'ƎꞀᗺⱯSIᗡ :sǝnןɐΛ pǝʍoןןⱯ",
"l2core.configuration.overlayZVal": "ʎɐןɹǝʌo ɹǝʇɔɐɹɐɥɔ ɯǝʇı ɟo ʇɥbıǝɥ ǝɥ⟘", "l2core.configuration.overlayZVal": "ʎɐןɹǝʌo ɹǝʇɔɐɹɐɥɔ ɯǝʇı ɟo ʇɥbıǝɥ ǝɥ⟘",
"l2core.configuration.overlayZVal.tooltip": "000000Ɩ ~ 000000Ɩ- :ǝbuɐᴚ", "l2core.configuration.overlayZVal.tooltip": "000000Ɩ ~ 000000Ɩ- :ǝbuɐᴚ \n0ϛᄅ :ʇןnɐɟǝᗡ ",
"l2core.configuration.renderOverlayIcons": "sǝıʇıʇuǝ uo suoɔı ʎɐןɹǝʌo ɹǝpuǝᴚ",
"l2core.configuration.renderOverlayIcons.tooltip": "",
"l2core.configuration.section.l2configs.l2core.client.toml": "uoıʇɐɹnbıɟuoƆ ʇuǝıןƆ ǝɹoƆᄅꞀ", "l2core.configuration.section.l2configs.l2core.client.toml": "uoıʇɐɹnbıɟuoƆ ʇuǝıןƆ ǝɹoƆᄅꞀ",
"l2core.configuration.section.l2configs.l2core.client.toml.title": "uoıʇɐɹnbıɟuoƆ ʇuǝıןƆ ǝɹoƆᄅꞀ", "l2core.configuration.section.l2configs.l2core.client.toml.title": "uoıʇɐɹnbıɟuoƆ ʇuǝıןƆ ǝɹoƆᄅꞀ",
"l2core.configuration.title": "uoıʇɐɹnbıɟuoƆ ǝɹoƆᄅꞀ", "l2core.configuration.title": "uoıʇɐɹnbıɟuoƆ ǝɹoƆᄅꞀ",

View File

@@ -2,7 +2,9 @@
"l2core.configuration.addEnchantmentDescription": "Add Enchantment Descriptions", "l2core.configuration.addEnchantmentDescription": "Add Enchantment Descriptions",
"l2core.configuration.addEnchantmentDescription.tooltip": "Allowed Values: DISABLE, SHIFT_ONLY, ALWAYS", "l2core.configuration.addEnchantmentDescription.tooltip": "Allowed Values: DISABLE, SHIFT_ONLY, ALWAYS",
"l2core.configuration.overlayZVal": "The height of item character overlay", "l2core.configuration.overlayZVal": "The height of item character overlay",
"l2core.configuration.overlayZVal.tooltip": "Range: -1000000 ~ 1000000", "l2core.configuration.overlayZVal.tooltip": " Default: 250\n Range: -1000000 ~ 1000000",
"l2core.configuration.renderOverlayIcons": "Render overlay icons on entities",
"l2core.configuration.renderOverlayIcons.tooltip": "",
"l2core.configuration.section.l2configs.l2core.client.toml": "L2Core Client Configuration", "l2core.configuration.section.l2configs.l2core.client.toml": "L2Core Client Configuration",
"l2core.configuration.section.l2configs.l2core.client.toml.title": "L2Core Client Configuration", "l2core.configuration.section.l2configs.l2core.client.toml.title": "L2Core Client Configuration",
"l2core.configuration.title": "L2Core Configuration", "l2core.configuration.title": "L2Core Configuration",

View File

@@ -3,22 +3,28 @@ package dev.xkmc.l2core.base.effects;
import dev.xkmc.l2core.base.effects.api.ForceEffect; 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.EntityType;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
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;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set;
import java.util.function.Predicate; import java.util.function.Predicate;
public class EffectUtil { public class EffectUtil {
private static final Set<EntityType<?>> INVALID = new HashSet<>();
/** /**
* 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 synchronized static void forceAddEffect(LivingEntity e, MobEffectInstance ins, @Nullable Entity source) {
if (INVALID.contains(e.getType())) return;
MobEffectInstance old = e.activeEffects.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);
@@ -27,7 +33,12 @@ public class EffectUtil {
} }
NeoForge.EVENT_BUS.post(new MobEffectEvent.Added(e, old, ins, source)); NeoForge.EVENT_BUS.post(new MobEffectEvent.Added(e, old, ins, source));
if (old == null) { if (old == null) {
try {
e.activeEffects.put(ins.getEffect(), ins); e.activeEffects.put(ins.getEffect(), ins);
} catch (Exception ignored) {
INVALID.add(e.getType());
return;
}
e.onEffectAdded(ins, source); e.onEffectAdded(ins, source);
ins.onEffectAdded(e); ins.onEffectAdded(e);
} else if (old.update(ins)) { } else if (old.update(ins)) {

View File

@@ -0,0 +1,37 @@
package dev.xkmc.l2core.base.worldgen;
import com.mojang.serialization.MapCodec;
import dev.xkmc.l2core.init.L2LibReg;
import dev.xkmc.l2core.serial.configval.DoubleConfigValue;
import net.minecraft.core.BlockPos;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
import net.minecraft.world.level.levelgen.placement.RepeatingPlacement;
import java.util.function.DoubleSupplier;
public class ConfigChancePlacement extends RepeatingPlacement {
public static final MapCodec<ConfigChancePlacement> CODEC = DoubleConfigValue.CODEC.fieldOf("chance").xmap(ConfigChancePlacement::new, e -> e.chance);
private final DoubleSupplier chance;
private ConfigChancePlacement(DoubleSupplier chance) {
this.chance = chance;
}
public static ConfigChancePlacement of(DoubleSupplier count) {
return new ConfigChancePlacement(count);
}
@Override
protected int count(RandomSource random, BlockPos pos) {
double val = chance.getAsDouble();
int ans = (int) val;
return ans + (random.nextFloat() < val - ans ? 1 : 0);
}
@Override
public PlacementModifierType<?> type() {
return L2LibReg.PM_CHANCE.get();
}
}

View File

@@ -0,0 +1,39 @@
package dev.xkmc.l2core.base.worldgen;
import com.mojang.serialization.MapCodec;
import dev.xkmc.l2core.init.L2LibReg;
import dev.xkmc.l2core.serial.configval.DoubleConfigValue;
import net.minecraft.core.BlockPos;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.levelgen.placement.PlacementContext;
import net.minecraft.world.level.levelgen.placement.PlacementFilter;
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
import java.util.function.DoubleSupplier;
public class ConfigRarityFilter extends PlacementFilter {
public static final MapCodec<ConfigRarityFilter> CODEC =
DoubleConfigValue.CODEC.fieldOf("chance").xmap(ConfigRarityFilter::new, e -> e.chance);
private final DoubleSupplier chance;
private ConfigRarityFilter(DoubleSupplier chance) {
this.chance = chance;
}
public static ConfigRarityFilter of(DoubleSupplier chance) {
return new ConfigRarityFilter(chance);
}
@Override
protected boolean shouldPlace(PlacementContext context, RandomSource random, BlockPos pos) {
return random.nextFloat() < this.chance.getAsDouble();
}
@Override
public PlacementModifierType<?> type() {
return L2LibReg.PM_RARITY.get();
}
}

View File

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

View File

@@ -2,14 +2,17 @@ package dev.xkmc.l2core.capability.conditionals;
import dev.xkmc.l2core.init.L2LibReg; import dev.xkmc.l2core.init.L2LibReg;
import dev.xkmc.l2core.util.Proxy; import dev.xkmc.l2core.util.Proxy;
import dev.xkmc.l2serial.serialization.codec.PacketCodec;
import dev.xkmc.l2serial.util.Wrappers; import dev.xkmc.l2serial.util.Wrappers;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
public class ClientDataHandler { public class ClientDataHandler {
public static <T extends ConditionalToken> void handle(TokenKey<T> key, T token) { public static <T extends ConditionalToken> void handle(TokenKey<T> key, byte[] data) {
Player player = Proxy.getClientPlayer(); Player player = Proxy.getClientPlayer();
if (player == null) return; if (player == null) return;
var buf = PacketCodec.decode(player.registryAccess(), data);
T token = Wrappers.cast(PacketCodec.from(buf, ConditionalToken.class, null));
ConditionalToken old = L2LibReg.CONDITIONAL.type().getOrCreate(player).data.put(key, token); ConditionalToken old = L2LibReg.CONDITIONAL.type().getOrCreate(player).data.put(key, token);
if (token instanceof NetworkSensitiveToken<?> t) { if (token instanceof NetworkSensitiveToken<?> t) {
t.onSync(Wrappers.cast(old), player); t.onSync(Wrappers.cast(old), player);

View File

@@ -10,7 +10,7 @@ public interface NetworkSensitiveToken<T extends ConditionalToken> {
void onSync(@Nullable T old, Player player); void onSync(@Nullable T old, Player player);
default void sync(TokenKey<T> key, T token, ServerPlayer sp) { default void sync(TokenKey<T> key, T token, ServerPlayer sp) {
L2Core.PACKET_HANDLER.toClientPlayer(TokenToClient.of(key, token), sp); L2Core.PACKET_HANDLER.toClientPlayer(TokenToClient.of(sp.registryAccess(), key, token), sp);
} }
} }

View File

@@ -1,20 +1,23 @@
package dev.xkmc.l2core.capability.conditionals; package dev.xkmc.l2core.capability.conditionals;
import dev.xkmc.l2serial.network.SerialPacketBase; import dev.xkmc.l2serial.network.SerialPacketBase;
import dev.xkmc.l2serial.serialization.codec.PacketCodec;
import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
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 TokenToClient(ResourceLocation id, ConditionalToken token) public record TokenToClient(ResourceLocation id, byte[] data)
implements SerialPacketBase<TokenToClient> { implements SerialPacketBase<TokenToClient> {
public static <T extends ConditionalToken> TokenToClient of(TokenKey<T> key, T token) { public static <T extends ConditionalToken> TokenToClient of(RegistryAccess access, TokenKey<T> key, T token) {
return new TokenToClient(key.asLocation(), token); var data = PacketCodec.toBytes(access, token, ConditionalToken.class, e -> true);
return new TokenToClient(key.asLocation(), data);
} }
@Override @Override
public void handle(@Nullable Player player) { public void handle(@Nullable Player player) {
ClientDataHandler.handle(TokenKey.of(id), token); ClientDataHandler.handle(TokenKey.of(id), data);
} }
} }

View File

@@ -6,9 +6,14 @@ import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeType; import mezz.jei.api.recipe.RecipeType;
import mezz.jei.api.recipe.category.IRecipeCategory; import mezz.jei.api.recipe.category.IRecipeCategory;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeInput;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@@ -27,6 +32,13 @@ public abstract class BaseRecipeCategory<T, C extends BaseRecipeCategory<T, C>>
this.type = new RecipeType<>(name, cls); this.type = new RecipeType<>(name, cls);
} }
public <R extends Recipe<I>, I extends RecipeInput> List<R> getAll(net.minecraft.world.item.crafting.RecipeType<R> type) {
var level = Minecraft.getInstance().level;
if (level == null) return List.of();
return level.getRecipeManager().getAllRecipesFor(type)
.stream().map(RecipeHolder::value).toList();
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public final C getThis() { public final C getThis() {
return (C) this; return (C) this;

View File

@@ -1,27 +1,23 @@
package dev.xkmc.l2core.events; package dev.xkmc.l2core.events;
import dev.xkmc.l2core.capability.attachment.GeneralCapabilityHolder;
import dev.xkmc.l2core.capability.player.PlayerCapabilityHolder; import dev.xkmc.l2core.capability.player.PlayerCapabilityHolder;
import dev.xkmc.l2core.init.L2Core; import dev.xkmc.l2core.init.L2Core;
import dev.xkmc.l2serial.util.Wrappers;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.LivingEntity;
import net.neoforged.bus.api.EventPriority; import net.neoforged.bus.api.EventPriority;
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.neoforge.event.entity.EntityJoinLevelEvent;
import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.entity.player.PlayerEvent;
import net.neoforged.neoforge.event.tick.EntityTickEvent; import net.neoforged.neoforge.event.tick.PlayerTickEvent;
@EventBusSubscriber(modid = L2Core.MODID, bus = EventBusSubscriber.Bus.GAME) @EventBusSubscriber(modid = L2Core.MODID, bus = EventBusSubscriber.Bus.GAME)
public class BaseCapabilityEvents { public class BaseCapabilityEvents {
@SubscribeEvent @SubscribeEvent
public static void onLivingTick(EntityTickEvent.Post event) { public static void onPlayerTick(PlayerTickEvent.Post event) {
if (event.getEntity() instanceof LivingEntity le && le.isAlive()) { if (event.getEntity().isAlive())
for (GeneralCapabilityHolder<?, ?> holder : GeneralCapabilityHolder.INTERNAL_MAP.values()) { for (PlayerCapabilityHolder<?> holder : PlayerCapabilityHolder.INTERNAL_MAP.values()) {
if (holder.isFor(event.getEntity())) holder.getOrCreate(event.getEntity()).tick(event.getEntity());
holder.getOrCreate(Wrappers.cast(event.getEntity())).tick(Wrappers.cast(event.getEntity()));
}
} }
} }
@@ -30,6 +26,13 @@ public class BaseCapabilityEvents {
for (PlayerCapabilityHolder<?> holder : PlayerCapabilityHolder.INTERNAL_MAP.values()) { for (PlayerCapabilityHolder<?> holder : PlayerCapabilityHolder.INTERNAL_MAP.values()) {
ServerPlayer e = (ServerPlayer) event.getEntity(); ServerPlayer e = (ServerPlayer) event.getEntity();
holder.getOrCreate(e).onClone(e, event.isWasDeath()); holder.getOrCreate(e).onClone(e, event.isWasDeath());
}
}
@SubscribeEvent(priority = EventPriority.LOW)
public static void onPlayerJoinLevel(EntityJoinLevelEvent event) {
if (!(event.getEntity() instanceof ServerPlayer e)) return;
for (PlayerCapabilityHolder<?> holder : PlayerCapabilityHolder.INTERNAL_MAP.values()) {
holder.network.toClient(e); holder.network.toClient(e);
holder.network.toTracking(e); holder.network.toTracking(e);
} }

View File

@@ -9,6 +9,7 @@ import dev.xkmc.l2core.base.effects.ClientEffectCap;
import dev.xkmc.l2core.base.effects.EffectToClient; import dev.xkmc.l2core.base.effects.EffectToClient;
import dev.xkmc.l2core.base.effects.api.*; import dev.xkmc.l2core.base.effects.api.*;
import dev.xkmc.l2core.init.L2Core; import dev.xkmc.l2core.init.L2Core;
import dev.xkmc.l2core.init.L2CoreConfig;
import dev.xkmc.l2core.init.L2LibReg; import dev.xkmc.l2core.init.L2LibReg;
import dev.xkmc.l2core.util.Proxy; import dev.xkmc.l2core.util.Proxy;
import net.minecraft.Util; import net.minecraft.Util;
@@ -76,10 +77,18 @@ public class ClientEffectRenderEvents {
.createCompositeState(false) .createCompositeState(false)
)); ));
public static RenderType get2DIcon(ResourceLocation id) {
return ICON_TYPE.apply(id);
}
@SubscribeEvent @SubscribeEvent
public static void levelRenderLast(RenderLevelStageEvent event) { public static void levelRenderLast(RenderLevelStageEvent event) {
if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_WEATHER) return; if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_WEATHER) return;
if (ICONS.isEmpty()) return;
if (!L2CoreConfig.CLIENT.renderOverlayIcons.get()) {
ICONS.clear();
return;
}
DUMMY.setupRenderState(); DUMMY.setupRenderState();
DUMMY.clearRenderState(); DUMMY.clearRenderState();
MultiBufferSource.BufferSource buffers = Minecraft.getInstance().renderBuffers().bufferSource(); MultiBufferSource.BufferSource buffers = Minecraft.getInstance().renderBuffers().bufferSource();
@@ -123,6 +132,10 @@ public class ClientEffectRenderEvents {
} }
} }
if (entity == Minecraft.getInstance().getCameraEntity()) {
return;
}
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);

View File

@@ -1,7 +1,6 @@
package dev.xkmc.l2core.events; package dev.xkmc.l2core.events;
import com.mojang.datafixers.util.Either; import com.mojang.datafixers.util.Either;
import dev.xkmc.l2core.init.L2Core;
import dev.xkmc.l2core.init.L2CoreConfig; import dev.xkmc.l2core.init.L2CoreConfig;
import dev.xkmc.l2core.init.L2LibReg; import dev.xkmc.l2core.init.L2LibReg;
import dev.xkmc.l2core.init.reg.ench.CustomDescEnchantment; import dev.xkmc.l2core.init.reg.ench.CustomDescEnchantment;
@@ -19,9 +18,9 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.bus.api.EventPriority; import net.neoforged.bus.api.EventPriority;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.event.entity.player.ItemTooltipEvent; import net.neoforged.neoforge.event.entity.player.ItemTooltipEvent;
import java.util.ArrayList; import java.util.ArrayList;
@@ -29,13 +28,13 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.stream.Stream; import java.util.stream.Stream;
@EventBusSubscriber(value = Dist.CLIENT, modid = L2Core.MODID, bus = EventBusSubscriber.Bus.GAME)
public class ClientEventHandler { public class ClientEventHandler {
public enum EnchDesc { public enum EnchDesc {
DISABLE, SHIFT_ONLY, ALWAYS DISABLE, SHIFT_ONLY, ALWAYS
} }
@OnlyIn(Dist.CLIENT)
@SubscribeEvent(priority = EventPriority.LOW) @SubscribeEvent(priority = EventPriority.LOW)
public static void modifyItemTooltip(ItemTooltipEvent event) { public static void modifyItemTooltip(ItemTooltipEvent event) {
var config = L2CoreConfig.CLIENT.addEnchantmentDescription.get(); var config = L2CoreConfig.CLIENT.addEnchantmentDescription.get();
@@ -61,7 +60,7 @@ public class ClientEventHandler {
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
Component comp = list.get(i); Component comp = list.get(i);
Component lit; Component lit;
if (comp.getContents() instanceof PlainTextContents.LiteralContents txt && comp.getSiblings().size() == 1) { if (comp.getContents() instanceof PlainTextContents txt && !comp.getSiblings().isEmpty()) {
comp = comp.getSiblings().getFirst(); comp = comp.getSiblings().getFirst();
lit = Component.literal(txt.text()); lit = Component.literal(txt.text());
} else lit = Component.empty(); } else lit = Component.empty();

View File

@@ -3,13 +3,17 @@ 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.events.ClientEventHandler;
import dev.xkmc.l2core.init.reg.registrate.L2Registrate; import dev.xkmc.l2core.init.reg.registrate.L2Registrate;
import dev.xkmc.l2core.serial.config.SyncPacket; 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.minecraft.resources.ResourceLocation;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.ModList;
import net.neoforged.fml.common.Mod; import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.common.NeoForge;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@@ -31,11 +35,15 @@ public class L2Core {
e -> e.create(SyncPacket.class, PLAY_TO_CLIENT) e -> e.create(SyncPacket.class, PLAY_TO_CLIENT)
); );
public L2Core(IEventBus bus) { public L2Core(IEventBus bus, Dist currentDist) {
L2LibReg.register(); L2LibReg.register();
L2CoreConfig.init(); L2CoreConfig.init();
Handlers.register(); Handlers.register();
REGISTRATE.addDataGenerator(L2TagGen.EFF_TAGS, L2TagGen::onEffectTagGen); REGISTRATE.addDataGenerator(L2TagGen.EFF_TAGS, L2TagGen::onEffectTagGen);
if (!ModList.get().isLoaded("enchdesc") && currentDist == Dist.CLIENT) {
NeoForge.EVENT_BUS.register(ClientEventHandler.class);
}
} }
public static ResourceLocation loc(String id) { public static ResourceLocation loc(String id) {

View File

@@ -10,6 +10,7 @@ public class L2CoreConfig {
public final ModConfigSpec.IntValue overlayZVal; public final ModConfigSpec.IntValue overlayZVal;
public final ModConfigSpec.EnumValue<ClientEventHandler.EnchDesc> addEnchantmentDescription; public final ModConfigSpec.EnumValue<ClientEventHandler.EnchDesc> addEnchantmentDescription;
public final ModConfigSpec.BooleanValue renderOverlayIcons;
Client(Builder builder) { Client(Builder builder) {
markL2(); markL2();
@@ -17,6 +18,8 @@ public class L2CoreConfig {
.defineInRange("overlayZVal", 250, -1000000, 1000000); .defineInRange("overlayZVal", 250, -1000000, 1000000);
addEnchantmentDescription = builder.text("Add Enchantment Descriptions") addEnchantmentDescription = builder.text("Add Enchantment Descriptions")
.defineEnum("addEnchantmentDescription", ClientEventHandler.EnchDesc.ALWAYS); .defineEnum("addEnchantmentDescription", ClientEventHandler.EnchDesc.ALWAYS);
renderOverlayIcons = builder.text("Render overlay icons on entities")
.define("renderOverlayIcons", true);
} }
} }

View File

@@ -2,6 +2,8 @@ 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.base.worldgen.ConfigChancePlacement;
import dev.xkmc.l2core.base.worldgen.ConfigRarityFilter;
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.conditionals.PlayerFlagData;
import dev.xkmc.l2core.capability.player.PlayerCapabilityNetworkHandler; import dev.xkmc.l2core.capability.player.PlayerCapabilityNetworkHandler;
@@ -21,6 +23,7 @@ import dev.xkmc.l2core.serial.loot.PlayerFlagCondition;
import dev.xkmc.l2serial.serialization.codec.MapCodecAdaptor; import dev.xkmc.l2serial.serialization.codec.MapCodecAdaptor;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType; import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType;
import net.neoforged.neoforge.common.conditions.ICondition; import net.neoforged.neoforge.common.conditions.ICondition;
import net.neoforged.neoforge.common.loot.IGlobalLootModifier; import net.neoforged.neoforge.common.loot.IGlobalLootModifier;
@@ -73,6 +76,10 @@ public class L2LibReg {
public static final EECVal.Special<EnchColor> COLOR = ENCH_REG.special("color", EnchColor.CODEC); public static final EECVal.Special<EnchColor> COLOR = ENCH_REG.special("color", EnchColor.CODEC);
public static final EECVal.Special<LegacyEnchantment> LEGACY = ENCH_REG.special("legacy", ENCH.reg().byNameCodec()); public static final EECVal.Special<LegacyEnchantment> LEGACY = ENCH_REG.special("legacy", ENCH.reg().byNameCodec());
public static final SR<PlacementModifierType<?>> PM = SR.of(REG, BuiltInRegistries.PLACEMENT_MODIFIER_TYPE);
public static final Val<PlacementModifierType<ConfigRarityFilter>> PM_RARITY = PM.reg("rarity", () -> () -> ConfigRarityFilter.CODEC);
public static final Val<PlacementModifierType<ConfigChancePlacement>> PM_CHANCE = PM.reg("chance", () -> () -> ConfigChancePlacement.CODEC);
public static void register() { public static void register() {
} }

View File

@@ -33,25 +33,34 @@ public interface EnchVal {
ResourceKey<Enchantment> id(); ResourceKey<Enchantment> id();
@DataGenOnly @DataGenOnly
Holder<Enchantment> datagenDirect(RegistrateProvider pvd); Holder<Enchantment> datagenDirect();
@DataGenOnly
default Holder<Enchantment> datagenDirect(RegistrateProvider pvd) {
return datagenDirect();
}
default Optional<Holder<Enchantment>> safeHolder() {
return Optional.ofNullable(CommonHooks.resolveLookup(Registries.ENCHANTMENT)).flatMap(e -> e.get(id()));
}
default Holder<Enchantment> holder() { default Holder<Enchantment> holder() {
return Optional.ofNullable(CommonHooks.resolveLookup(Registries.ENCHANTMENT)).orElseThrow().getOrThrow(id()); return safeHolder().orElseThrow();
} }
default int getLv(ItemStack stack) { default int getLv(ItemStack stack) {
return stack.getEnchantmentLevel(holder()); return safeHolder().map(stack::getEnchantmentLevel).orElse(0);
} }
default int getLvIntrinsic(ItemStack stack) { default int getLvIntrinsic(ItemStack stack) {
return stack.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY).getLevel(holder()); return safeHolder().map(e -> stack.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY).getLevel(e)).orElse(0);
} }
interface Impl extends EnchVal { interface Impl extends EnchVal {
Lazy<Builder> builder(); Lazy<Builder> builder();
@Override @Override
default Holder<Enchantment> datagenDirect(RegistrateProvider pvd) { default Holder<Enchantment> datagenDirect() {
var val = builder().get().cache; var val = builder().get().cache;
if (val == null) throw new IllegalStateException("Enchantment is not built yet"); if (val == null) throw new IllegalStateException("Enchantment is not built yet");
return new DataGenHolder<>(id(), val); return new DataGenHolder<>(id(), val);

View File

@@ -14,6 +14,7 @@ import dev.xkmc.l2core.init.L2Core;
import dev.xkmc.l2core.init.reg.simple.Val; import dev.xkmc.l2core.init.reg.simple.Val;
import dev.xkmc.l2core.util.ConfigInit; import dev.xkmc.l2core.util.ConfigInit;
import dev.xkmc.l2serial.serialization.custom_handler.CodecHandler; import dev.xkmc.l2serial.serialization.custom_handler.CodecHandler;
import dev.xkmc.l2serial.serialization.custom_handler.Handlers;
import dev.xkmc.l2serial.util.ModContainerHack; import dev.xkmc.l2serial.util.ModContainerHack;
import dev.xkmc.l2serial.util.Wrappers; import dev.xkmc.l2serial.util.Wrappers;
import net.minecraft.client.particle.ParticleEngine; import net.minecraft.client.particle.ParticleEngine;
@@ -21,7 +22,6 @@ import net.minecraft.client.particle.ParticleProvider;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.core.particles.ParticleOptions; import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleType; import net.minecraft.core.particles.ParticleType;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.ByteBufCodecs;
@@ -101,6 +101,10 @@ public class L2Registrate extends AbstractRegistrate<L2Registrate> {
} }
public <T extends Potion> SimpleEntry<Potion> potion(String name, NonNullSupplier<T> sup) { public <T extends Potion> SimpleEntry<Potion> potion(String name, NonNullSupplier<T> sup) {
return potion(name, RegistrateLangProvider.toEnglishName(name), sup);
}
public <T extends Potion> SimpleEntry<Potion> potion(String name, String desc, NonNullSupplier<T> sup) {
RegistryEntry<Potion, T> ans = entry(name, (cb) -> new NoConfigBuilder<>(this, this, name, cb, RegistryEntry<Potion, T> ans = entry(name, (cb) -> new NoConfigBuilder<>(this, this, name, cb,
Registries.POTION, sup)).register(); Registries.POTION, sup)).register();
if (doDataGen.get()) { if (doDataGen.get()) {
@@ -111,7 +115,7 @@ public class L2Registrate extends AbstractRegistrate<L2Registrate> {
String str = item.getDescriptionId() + ".effect." + name; String str = item.getDescriptionId() + ".effect." + name;
String pref_name = RegistrateLangProvider.toEnglishName(prefs[prefs.length - 1]); String pref_name = RegistrateLangProvider.toEnglishName(prefs[prefs.length - 1]);
if (item == Items.TIPPED_ARROW) pref_name = "Arrow"; if (item == Items.TIPPED_ARROW) pref_name = "Arrow";
addRawLang(str, pref_name + " of " + RegistrateLangProvider.toEnglishName(name)); addRawLang(str, pref_name + " of " + desc);
} }
} }
return new SimpleEntry<>(ans); return new SimpleEntry<>(ans);
@@ -142,6 +146,7 @@ public class L2Registrate extends AbstractRegistrate<L2Registrate> {
cons.accept(ans); cons.accept(ans);
var reg = ans.create(); var reg = ans.create();
new CodecHandler<>(Wrappers.cast(cls), reg.byNameCodec(), ByteBufCodecs.fromCodecWithRegistries(reg.byNameCodec())); new CodecHandler<>(Wrappers.cast(cls), reg.byNameCodec(), ByteBufCodecs.fromCodecWithRegistries(reg.byNameCodec()));
Handlers.registerReg(Wrappers.cast(cls), key);
OneTimeEventReceiver.addModListener(this, NewRegistryEvent.class, (e) -> e.register(reg)); OneTimeEventReceiver.addModListener(this, NewRegistryEvent.class, (e) -> e.register(reg));
return new RegistryInstance<>(reg, key); return new RegistryInstance<>(reg, key);
} }
@@ -242,13 +247,6 @@ public class L2Registrate extends AbstractRegistrate<L2Registrate> {
before = e.id; 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) { private static boolean known(ResourceLocation id) {

View File

@@ -1,6 +1,7 @@
package dev.xkmc.l2core.init.reg.registrate; package dev.xkmc.l2core.init.reg.registrate;
import dev.xkmc.l2serial.util.Wrappers; import dev.xkmc.l2serial.util.Wrappers;
import net.minecraft.core.Holder;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
@@ -46,4 +47,8 @@ public class NamedEntry<T extends NamedEntry<T>> {
return Wrappers.cast(this); return Wrappers.cast(this);
} }
public Holder<T> holder() {
return registry.get().wrapAsHolder(getThis());
}
} }

View File

@@ -0,0 +1,141 @@
package dev.xkmc.l2core.init.reg.registrate;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimaps;
import com.tterrag.registrate.providers.RegistrateLangProvider;
import net.minecraft.core.Holder;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.Potion;
import net.minecraft.world.item.alchemy.PotionBrewing;
import net.minecraft.world.item.alchemy.PotionContents;
import net.minecraft.world.item.alchemy.Potions;
import net.minecraft.world.level.ItemLike;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.brewing.RegisterBrewingRecipesEvent;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.TreeSet;
import java.util.function.Consumer;
import java.util.stream.Stream;
public class PotionBuilder {
public static class TabHolder {
private final ListMultimap<String, Holder<Potion>> potions;
private final String modid;
public TabHolder(String modid) {
potions = Multimaps.newListMultimap(new LinkedHashMap<>(), ArrayList::new);
this.modid = modid;
}
public Stream<Holder<Potion>> stream() {
List<String> ans = new ArrayList<>();
ans.add(modid);
var set = new TreeSet<>(potions.keySet());
set.remove(modid);
ans.addAll(set);
return ans.stream().flatMap(e -> potions.get(e).stream());
}
public synchronized void add(String modid, SimpleEntry<Potion> ans) {
potions.put(modid, ans);
}
}
private final List<Consumer<PotionBrewing.Builder>> recipes = new ArrayList<>();
private final TabHolder tab;
private final L2Registrate reg;
private PotionBuilder(L2Registrate reg, TabHolder tab) {
this.reg = reg;
this.tab = tab;
NeoForge.EVENT_BUS.addListener(this::registerBrewingRecipe);
}
public PotionBuilder(L2Registrate reg, PotionBuilder parent) {
this(reg, parent.tab);
}
public PotionBuilder(L2Registrate reg) {
this(reg, new TabHolder(reg.getModid()));
}
private void registerBrewingRecipe(RegisterBrewingRecipesEvent event) {
var builder = event.getBuilder();
recipes.forEach(e -> e.accept(builder));
}
public void addMix(Holder<Potion> source, ItemLike item, Holder<Potion> potion) {
recipes.add(e -> e.addMix(source, item.asItem(), potion));
}
public Holder<Potion> regPotion(String id, String name, Holder<MobEffect> sup, int dur, int amp) {
var ans = reg.potion(id, RegistrateLangProvider.toEnglishName(name), () -> new Potion(new MobEffectInstance(sup, dur, amp)));
tab.add(reg.getModid(), ans);
return ans;
}
public Holder<Potion> regPotion(String id, String nameId, Holder<MobEffect> sup, Holder<Potion> source, ItemLike item, int dur, int amp) {
var potion = regPotion(id, nameId, sup, dur, amp);
addMix(source, item, potion);
return potion;
}
public void regPotion2(String id, Holder<MobEffect> sup, ItemLike item, int dur, int durLong) {
var potion = regPotion(id, id, sup, Potions.AWKWARD, item, dur, 0);
regPotion("long_" + id, id, sup, potion, Items.REDSTONE, durLong, 0);
}
public void regPotion3(String id, Holder<MobEffect> sup, ItemLike item, int durStrong, int dur, int durLong, int amp, int ampStrong) {
var potion = regPotion(id, id, sup, Potions.AWKWARD, item, dur, amp);
regPotion("long_" + id, id, sup, potion, Items.REDSTONE, durLong, amp);
regPotion("strong_" + id, id, sup, potion, Items.GLOWSTONE_DUST, durStrong, ampStrong);
}
public void regPotion3(String id, Holder<MobEffect> sup, ItemLike item, int durStrong, int dur, int durLong, int amp, int ampStrong, ItemLike longItem, ItemLike strongItem) {
var potion = regPotion(id, id, sup, Potions.AWKWARD, item, dur, amp);
regPotion("long_" + id, id, sup, potion, longItem, durLong, amp);
regPotion("strong_" + id, id, sup, potion, strongItem, durStrong, ampStrong);
}
public void interleave(String id, Holder<MobEffect> sup, int durStrong, int dur, int durLong, int amp, int ampStrong,
ItemLike a, Holder<Potion> ap, @Nullable Holder<Potion> lap, @Nullable Holder<Potion> sap,
ItemLike b, Holder<Potion> bp, @Nullable Holder<Potion> lbp, @Nullable Holder<Potion> sbp) {
var potion = regPotion(id, id, sup, dur, amp);
var longPotion = regPotion("long_" + id, id, sup, potion, Items.REDSTONE, durLong, amp);
var strongPotion = regPotion("strong_" + id, id, sup, potion, Items.GLOWSTONE_DUST, durStrong, ampStrong);
addMix(ap, a, potion);
addMix(bp, b, potion);
if (lap != null) addMix(lap, a, longPotion);
if (lbp != null) addMix(lbp, b, longPotion);
if (sap != null) addMix(sap, a, strongPotion);
if (sbp != null) addMix(sbp, b, strongPotion);
}
public void regTab(ResourceKey<CreativeModeTab> key) {
regTab(key, Items.POTION);
regTab(key, Items.SPLASH_POTION);
regTab(key, Items.LINGERING_POTION);
}
private void regTab(ResourceKey<CreativeModeTab> key, Item potion) {
reg.modifyCreativeModeTab(key, m -> tab.stream().forEach(e ->
m.accept(PotionContents.createItemStack(potion, e),
CreativeModeTab.TabVisibility.PARENT_TAB_ONLY)));
}
}

View File

@@ -8,6 +8,7 @@ import dev.xkmc.l2core.capability.player.PlayerCapabilityTemplate;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.neoforged.neoforge.attachment.AttachmentHolder; import net.neoforged.neoforge.attachment.AttachmentHolder;
import net.neoforged.neoforge.attachment.AttachmentType; import net.neoforged.neoforge.attachment.AttachmentType;
import net.neoforged.neoforge.attachment.IAttachmentHolder;
import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister; import net.neoforged.neoforge.registries.DeferredRegister;
import net.neoforged.neoforge.registries.NeoForgeRegistries; import net.neoforged.neoforge.registries.NeoForgeRegistries;
@@ -32,7 +33,7 @@ public record AttReg(DeferredRegister<AttachmentType<?>> att) {
return reg(id, type); return reg(id, type);
} }
public <E extends GeneralCapabilityTemplate<H, E>, H extends AttachmentHolder> AttVal.CapVal<H, E> public <E extends GeneralCapabilityTemplate<H, E>, H extends IAttachmentHolder> AttVal.CapVal<H, E>
entity(String id, Class<E> holder_class, Supplier<E> sup, Class<H> entity_class, Predicate<H> pred) { entity(String id, Class<E> holder_class, Supplier<E> sup, Class<H> entity_class, Predicate<H> pred) {
ResourceLocation rl = ResourceLocation.fromNamespaceAndPath(att.getNamespace(), id); ResourceLocation rl = ResourceLocation.fromNamespaceAndPath(att.getNamespace(), id);
var type = new GeneralCapabilityHolder<>(rl, holder_class, sup, entity_class, pred); var type = new GeneralCapabilityHolder<>(rl, holder_class, sup, entity_class, pred);
@@ -62,7 +63,7 @@ public record AttReg(DeferredRegister<AttachmentType<?>> att) {
} }
private record CapValImpl<E extends AttachmentHolder, T extends GeneralCapabilityTemplate<E, T>>( private record CapValImpl<E extends IAttachmentHolder, T extends GeneralCapabilityTemplate<E, T>>(
DeferredHolder<AttachmentType<?>, AttachmentType<T>> val, GeneralCapabilityHolder<E, T> type DeferredHolder<AttachmentType<?>, AttachmentType<T>> val, GeneralCapabilityHolder<E, T> type
) implements AttVal.CapVal<E, T> { ) implements AttVal.CapVal<E, T> {

View File

@@ -7,12 +7,13 @@ import dev.xkmc.l2core.capability.player.PlayerCapabilityHolder;
import dev.xkmc.l2core.capability.player.PlayerCapabilityTemplate; import dev.xkmc.l2core.capability.player.PlayerCapabilityTemplate;
import net.neoforged.neoforge.attachment.AttachmentHolder; import net.neoforged.neoforge.attachment.AttachmentHolder;
import net.neoforged.neoforge.attachment.AttachmentType; import net.neoforged.neoforge.attachment.AttachmentType;
import net.neoforged.neoforge.attachment.IAttachmentHolder;
public interface AttVal<T, H extends AttachmentDef<T>> extends Val<AttachmentType<T>> { public interface AttVal<T, H extends AttachmentDef<T>> extends Val<AttachmentType<T>> {
H type(); H type();
interface CapVal<E extends AttachmentHolder, T extends GeneralCapabilityTemplate<E, T>> interface CapVal<E extends IAttachmentHolder, T extends GeneralCapabilityTemplate<E, T>>
extends AttVal<T, GeneralCapabilityHolder<E, T>> { extends AttVal<T, GeneralCapabilityHolder<E, T>> {
} }

View File

@@ -3,9 +3,10 @@ package dev.xkmc.l2core.init.reg.varitem;
import com.tterrag.registrate.util.entry.ItemEntry; import com.tterrag.registrate.util.entry.ItemEntry;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.ItemLike;
import org.jetbrains.annotations.Nullable;
public class VarHolder<T extends Item> implements VarEntry<T>, ItemLike { import java.util.function.Supplier;
public class VarHolder<T extends Item> implements VarEntry<T>, ItemLike, Supplier<T> {
private final String str; private final String str;
private final VarBuilder<T> builder; private final VarBuilder<T> builder;
@@ -25,6 +26,11 @@ public class VarHolder<T extends Item> implements VarEntry<T>, ItemLike {
return item.asItem(); return item.asItem();
} }
@Override
public T get() {
return item.get();
}
@Override @Override
public String id() { public String id() {
return str; return str;

View File

@@ -2,7 +2,6 @@ package dev.xkmc.l2core.init.reg.varitem;
import com.google.gson.*; import com.google.gson.*;
import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Pair;
import com.tterrag.registrate.util.OneTimeEventReceiver;
import com.tterrag.registrate.util.entry.ItemEntry; import com.tterrag.registrate.util.entry.ItemEntry;
import dev.xkmc.l2core.init.L2Core; import dev.xkmc.l2core.init.L2Core;
import dev.xkmc.l2core.init.reg.registrate.L2Registrate; import dev.xkmc.l2core.init.reg.registrate.L2Registrate;
@@ -14,12 +13,10 @@ import net.neoforged.fml.loading.FMLPaths;
import net.neoforged.neoforge.registries.RegisterEvent; import net.neoforged.neoforge.registries.RegisterEvent;
import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Level;
import javax.annotation.Nullable;
import java.io.FileReader; import java.io.FileReader;
import java.io.FileWriter; import java.io.FileWriter;
import java.util.ArrayList; import java.util.*;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.function.Function; import java.util.function.Function;
@@ -41,7 +38,7 @@ public class VarItemInit<T extends Item> {
private final Function<ResourceLocation, T> func; private final Function<ResourceLocation, T> func;
private final VarBuilder<T> builder; private final VarBuilder<T> builder;
private final Map<String, VarEntry<T>> defaults = new LinkedHashMap<>(); private final Map<String, VarEntry<T>> defaults = new LinkedHashMap<>();
private final List<String> registered = new ArrayList<>(); private final Set<String> registered = new LinkedHashSet<>();
private final Map<String, ItemEntry<T>> results = new ConcurrentHashMap<>(); private final Map<String, ItemEntry<T>> results = new ConcurrentHashMap<>();
private VarItemInit(L2Registrate reg, ResourceLocation id, Function<ResourceLocation, T> func, VarBuilder<T> builder) { private VarItemInit(L2Registrate reg, ResourceLocation id, Function<ResourceLocation, T> func, VarBuilder<T> builder) {
@@ -49,7 +46,7 @@ public class VarItemInit<T extends Item> {
this.id = id; this.id = id;
this.func = func; this.func = func;
this.builder = builder; this.builder = builder;
reg.getModEventBus().addListener( EventPriority.HIGH, RegisterEvent.class, this::init); reg.getModEventBus().addListener(EventPriority.HIGH, RegisterEvent.class, this::init);
} }
public synchronized void add(List<String> defaults) { public synchronized void add(List<String> defaults) {
@@ -61,6 +58,11 @@ public class VarItemInit<T extends Item> {
return e; return e;
} }
@Nullable
public ItemEntry<T> get(String str) {
return results.get(str);
}
private synchronized void init(RegisterEvent event) { private synchronized void init(RegisterEvent event) {
if (event.getRegistry() != BuiltInRegistries.ITEM) return; if (event.getRegistry() != BuiltInRegistries.ITEM) return;
load(); load();
@@ -119,17 +121,24 @@ public class VarItemInit<T extends Item> {
private Pair<Boolean, List<String>> parseFile(JsonElement elem) { private Pair<Boolean, List<String>> parseFile(JsonElement elem) {
if (!elem.isJsonArray()) return Pair.of(true, List.of()); if (!elem.isJsonArray()) return Pair.of(true, List.of());
List<String> ans = new ArrayList<>(); Set<String> ans = new LinkedHashSet<>(defaults.keySet());
Set<String> checker = new HashSet<>();
boolean err = false; boolean err = false;
for (var e : elem.getAsJsonArray()) { for (var e : elem.getAsJsonArray()) {
var rl = e.getAsString(); var rl = e.getAsString();
if (ResourceLocation.isValidPath(rl)) ans.add(rl); if (ResourceLocation.isValidPath(rl)) {
else { ans.add(rl);
checker.add(rl);
} else {
L2Core.LOGGER.error("Item ID {} for varitem type {} is invalid. Skipped", rl, id); L2Core.LOGGER.error("Item ID {} for varitem type {} is invalid. Skipped", rl, id);
err = true; err = true;
} }
} }
return Pair.of(err, ans); if (checker.size() != ans.size()) {
L2Core.LOGGER.error("Found missing default items for varitem type {}. Filling", id);
err = true;
}
return Pair.of(err, new ArrayList<>(ans));
} }
private record SimpleVarEntry<T extends Item>(String id) implements VarEntry<T> { private record SimpleVarEntry<T extends Item>(String id) implements VarEntry<T> {

View File

@@ -0,0 +1,17 @@
package dev.xkmc.l2core.mixin;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.item.CreativeModeTab;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(CreativeModeTab.class)
public class CreativeModeTabMixin {
@Override
public String toString() {
CreativeModeTab tab = (CreativeModeTab) (Object) this;
var key = BuiltInRegistries.CREATIVE_MODE_TAB.getKey(tab);
return key == null ? "[Unregistered]" : key.toString();
}
}

View File

@@ -12,6 +12,7 @@ public class BaseConfigType<T extends BaseConfig> {
public final PacketHandlerWithConfig parent; public final PacketHandlerWithConfig parent;
final Map<ResourceLocation, T> configs = new HashMap<>(); final Map<ResourceLocation, T> configs = new HashMap<>();
final Map<ResourceLocation, T> clientConfigs = new HashMap<>();
protected BaseConfigType(PacketHandlerWithConfig parent, String id, Class<T> cls) { protected BaseConfigType(PacketHandlerWithConfig parent, String id, Class<T> cls) {
this.parent = parent; this.parent = parent;
@@ -26,4 +27,11 @@ public class BaseConfigType<T extends BaseConfig> {
public void afterReload() { public void afterReload() {
} }
public void clientBeforeReload() {
clientConfigs.clear();
}
public void clientAfterReload() {
}
} }

View File

@@ -1,6 +1,7 @@
package dev.xkmc.l2core.serial.config; package dev.xkmc.l2core.serial.config;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.tterrag.registrate.providers.ProviderType;
import dev.xkmc.l2serial.serialization.codec.JsonCodec; import dev.xkmc.l2serial.serialization.codec.JsonCodec;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.data.CachedOutput; import net.minecraft.data.CachedOutput;

View File

@@ -1,16 +1,23 @@
package dev.xkmc.l2core.serial.config; package dev.xkmc.l2core.serial.config;
import dev.xkmc.l2core.util.ServerProxy;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
public class MergedConfigType<T extends BaseConfig> extends BaseConfigType<T> { public class MergedConfigType<T extends BaseConfig> extends BaseConfigType<T> {
private T result; private T result, clientResult;
MergedConfigType(PacketHandlerWithConfig parent, String id, Class<T> cls) { MergedConfigType(PacketHandlerWithConfig parent, String id, Class<T> cls) {
super(parent, id, cls); super(parent, id, cls);
} }
T load() { T load() {
if (ServerProxy.isOnClient())
return loadClient();
return loadServer();
}
T loadServer() {
if (result != null) { if (result != null) {
return result; return result;
} }
@@ -19,11 +26,28 @@ public class MergedConfigType<T extends BaseConfig> extends BaseConfigType<T> {
return result; return result;
} }
T loadClient() {
if (clientResult != null) {
return clientResult;
}
clientResult = new ConfigMerger<>(cls).apply(clientConfigs.values());
clientResult.id = ResourceLocation.fromNamespaceAndPath(parent.modid, id);
return clientResult;
}
@Override @Override
public void afterReload() { public void afterReload() {
result = null; result = null;
if (cls.isAnnotationPresent(ConfigLoadOnStart.class)) { if (cls.isAnnotationPresent(ConfigLoadOnStart.class)) {
load(); loadServer();
}
}
@Override
public void clientAfterReload() {
clientResult = null;
if (cls.isAnnotationPresent(ConfigLoadOnStart.class)) {
loadClient();
} }
} }

View File

@@ -114,25 +114,30 @@ public class PacketHandlerWithConfig extends PacketHandler {
private <T extends BaseConfig> void addJson(BaseConfigType<T> type, ResourceLocation k, JsonElement v) { private <T extends BaseConfig> void addJson(BaseConfigType<T> type, ResourceLocation k, JsonElement v) {
T config = new JsonCodec(getRegistryLookup()).from(v, type.cls, null); T config = new JsonCodec(getRegistryLookup()).from(v, type.cls, null);
if (config != null) { if (config != null) {
addConfig(type, k, config); addServerConfig(type, k, config);
} }
} }
private <T extends BaseConfig> void addConfig(BaseConfigType<T> type, ResourceLocation k, T config) { private <T extends BaseConfig> void addServerConfig(BaseConfigType<T> type, ResourceLocation k, T config) {
config.id = k; config.id = k;
type.configs.put(k, config); type.configs.put(k, config);
configs.add(new ConfigInstance(type.id, k, config)); configs.add(new ConfigInstance(type.id, k, config));
} }
private <T extends BaseConfig> void addClientConfig(BaseConfigType<T> type, ResourceLocation k, T config) {
config.id = k;
type.clientConfigs.put(k, config);
}
/** /**
* Called on client side only * Called on client side only
*/ */
public void apply(ArrayList<ConfigInstance> list) { public void apply(ArrayList<ConfigInstance> list) {
listener_before.forEach(Runnable::run); types.values().forEach(BaseConfigType::clientBeforeReload);
for (var e : list) { for (var e : list) {
addConfig(types.get(e.name), e.id(), Wrappers.cast(e.config)); addClientConfig(types.get(e.name), e.id(), Wrappers.cast(e.config));
} }
listener_after.forEach(Runnable::run); types.values().forEach(BaseConfigType::clientAfterReload);
} }
} }

View File

@@ -0,0 +1,53 @@
package dev.xkmc.l2core.serial.config;
import com.tterrag.registrate.AbstractRegistrate;
import com.tterrag.registrate.providers.ProviderType;
import com.tterrag.registrate.providers.RegistrateProvider;
import net.minecraft.core.HolderLookup;
import net.minecraft.data.CachedOutput;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.DataProvider;
import net.neoforged.fml.LogicalSide;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
public class RegistrateNestedProvider implements RegistrateProvider {
public static final ProviderType<RegistrateNestedProvider> TYPE = ProviderType.registerProvider("l2_custom", RegistrateNestedProvider::new);
private final List<DataProvider> list = new ArrayList<>();
private final AbstractRegistrate<?> reg;
private final DataGenerator gen;
private final CompletableFuture<HolderLookup.Provider> pvd;
public RegistrateNestedProvider(ProviderType.Context<RegistrateNestedProvider> ctx) {
this.reg = ctx.parent();
this.gen = ctx.event().getGenerator();
this.pvd = ctx.provider();
}
@Override
public LogicalSide getSide() {
return LogicalSide.SERVER;
}
public RegistrateNestedProvider add(BiFunction<DataGenerator, CompletableFuture<HolderLookup.Provider>, DataProvider> factory) {
list.add(factory.apply(gen, pvd));
return this;
}
@Override
public CompletableFuture<?> run(CachedOutput cachedOutput) {
reg.genData(TYPE, this);
return CompletableFuture.allOf(list.stream().map(e -> e.run(cachedOutput)).toArray(CompletableFuture[]::new));
}
@Override
public String getName() {
return "Custom Registrate Provider";
}
}

View File

@@ -5,6 +5,7 @@ import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.world.item.ItemStack; 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.Ingredient;
import net.minecraft.world.item.crafting.SmithingTransformRecipe; import net.minecraft.world.item.crafting.SmithingTransformRecipe;
@@ -14,7 +15,7 @@ import javax.annotation.ParametersAreNonnullByDefault;
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
public abstract class AbstractSmithingRecipe<T extends AbstractSmithingRecipe<T>> extends SmithingTransformRecipe { public abstract class AbstractSmithingRecipe<T extends AbstractSmithingRecipe<T>> extends SmithingTransformRecipe {
public static final Ingredient TEMPLATE_PLACEHOLDER = Ingredient.EMPTY; public static final Ingredient TEMPLATE_PLACEHOLDER = Ingredient.of(Items.PAPER);
public AbstractSmithingRecipe(Ingredient template, Ingredient base, Ingredient addition, ItemStack result) { public AbstractSmithingRecipe(Ingredient template, Ingredient base, Ingredient addition, ItemStack result) {
super(template, base, addition, result); super(template, base, addition, result);

View File

@@ -63,7 +63,7 @@ public class BaseRecipeBuilder<
.rewards(AdvancementRewards.Builder.recipe(id)) .rewards(AdvancementRewards.Builder.recipe(id))
.requirements(AdvancementRequirements.Strategy.OR); .requirements(AdvancementRequirements.Strategy.OR);
this.criteria.forEach(builder::addCriterion); this.criteria.forEach(builder::addCriterion);
id = ResourceLocation.fromNamespaceAndPath(id.getNamespace(), "recipes/" + id = ResourceLocation.fromNamespaceAndPath(id.getNamespace(),
BuiltInRegistries.RECIPE_SERIALIZER.getKey(type).getPath() + "/" + id.getPath()); BuiltInRegistries.RECIPE_SERIALIZER.getKey(type).getPath() + "/" + id.getPath());
pvd.accept(id, recipe, builder.build(id)); pvd.accept(id, recipe, builder.build(id));
} }

View File

@@ -5,8 +5,15 @@ import mezz.jei.api.gui.drawable.IDrawable;
import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeType; import mezz.jei.api.recipe.RecipeType;
import mezz.jei.api.recipe.category.IRecipeCategory; import mezz.jei.api.recipe.category.IRecipeCategory;
import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeInput;
import java.util.List;
@Deprecated(forRemoval = true)
public abstract class BaseRecipeCategory<T, C extends BaseRecipeCategory<T, C>> implements IRecipeCategory<T> { public abstract class BaseRecipeCategory<T, C extends BaseRecipeCategory<T, C>> implements IRecipeCategory<T> {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View File

@@ -1,9 +1,10 @@
package dev.xkmc.l2core.util; package dev.xkmc.l2core.util;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.RegistryAccess;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.fml.loading.FMLEnvironment; import net.neoforged.fml.loading.FMLEnvironment;
@@ -11,16 +12,15 @@ import net.neoforged.neoforge.server.ServerLifecycleHooks;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Optional; import java.util.Optional;
import java.util.function.BiConsumer;
public class Proxy { public class Proxy {
@Deprecated @Nullable
public static RegistryAccess getRegistryAccess() { public static Player getPlayer() {
if (FMLEnvironment.dist == Dist.CLIENT) { if (FMLEnvironment.dist == Dist.CLIENT) {
return Minecraft.getInstance().level.registryAccess(); return Minecraft.getInstance().player;
} }
return ServerLifecycleHooks.getCurrentServer().registryAccess(); return null;
} }
@Nullable @Nullable
@@ -28,9 +28,14 @@ public class Proxy {
if (FMLEnvironment.dist == Dist.CLIENT) { if (FMLEnvironment.dist == Dist.CLIENT) {
return Minecraft.getInstance().level; return Minecraft.getInstance().level;
} }
return ServerLifecycleHooks.getCurrentServer().overworld(); var server = ServerLifecycleHooks.getCurrentServer();
if (server != null) {
return server.overworld();
}
return null;
} }
@Deprecated
public static Optional<MinecraftServer> getServer() { public static Optional<MinecraftServer> getServer() {
return Optional.ofNullable(ServerLifecycleHooks.getCurrentServer()); return Optional.ofNullable(ServerLifecycleHooks.getCurrentServer());
} }
@@ -40,4 +45,7 @@ public class Proxy {
return Minecraft.getInstance().player; return Minecraft.getInstance().player;
} }
static boolean isOnClient() {
return getServer().isEmpty() || RenderSystem.isOnRenderThread();
}
} }

View File

@@ -0,0 +1,39 @@
package dev.xkmc.l2core.util;
import net.minecraft.core.RegistryAccess;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.Level;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.fml.loading.FMLEnvironment;
import net.neoforged.neoforge.server.ServerLifecycleHooks;
import javax.annotation.Nullable;
import java.util.Optional;
public class ServerProxy {
@Nullable
public static RegistryAccess getRegistryAccess() {
if (FMLEnvironment.dist == Dist.CLIENT) {
Level level = Proxy.getLevel();
if (level != null) {
return level.registryAccess();
}
}
var server = ServerLifecycleHooks.getCurrentServer();
if (server != null) {
return server.registryAccess();
}
return null;
}
public static Optional<MinecraftServer> getServer() {
return Optional.ofNullable(ServerLifecycleHooks.getCurrentServer());
}
public static boolean isOnClient() {
if (FMLEnvironment.dist == Dist.DEDICATED_SERVER) return false;
return Proxy.isOnClient();
}
}

View File

@@ -6,5 +6,7 @@
"l2core.configuration.overlayZVal.tooltip": "默认值250", "l2core.configuration.overlayZVal.tooltip": "默认值250",
"l2core.configuration.section.l2configs.l2core.client.toml": "莱特兰核心 - 客户端配置", "l2core.configuration.section.l2configs.l2core.client.toml": "莱特兰核心 - 客户端配置",
"l2core.configuration.section.l2configs.l2core.client.toml.title": "莱特兰核心 - 客户端配置", "l2core.configuration.section.l2configs.l2core.client.toml.title": "莱特兰核心 - 客户端配置",
"l2core.configuration.title": "莱特兰核心 - 配置" "l2core.configuration.title": "莱特兰核心 - 配置",
"l2core.configuration.renderOverlayIcons": "实体图标显示",
"l2core.configuration.renderOverlayIcons.tooltip": ""
} }

View File

@@ -4,6 +4,7 @@
"package": "dev.xkmc.l2core.mixin", "package": "dev.xkmc.l2core.mixin",
"compatibilityLevel": "JAVA_21", "compatibilityLevel": "JAVA_21",
"mixins": [ "mixins": [
"CreativeModeTabMixin"
], ],
"client": [ "client": [
], ],