Skip to content

Commit 64ef836

Browse files
authored
Merge pull request #8 from Magic-team-jvav/neoforge-dev/1.21.1
Neoforge dev/1.21.1
2 parents 49e74b6 + 4123121 commit 64ef836

65 files changed

Lines changed: 1941 additions & 772 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build.gradle

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,17 @@ idea {
177177
tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' }
178178

179179
tasks.register('runLangMerger', JavaExec) {
180-
group = 'mod development'
180+
group = 'mod development/internal'
181181
description = 'Language Merger'
182182
classpath = sourceSets.main.runtimeClasspath
183-
mainClass = 'org.confluence.lib.util.LangMerger'
183+
mainClass = 'org.confluence.lib.util.lang.LangMerger'
184+
args "../"
185+
}
186+
187+
tasks.register('runLangDistinctor', JavaExec) {
188+
group = 'mod development/internal'
189+
description = 'Language Distinctor'
190+
classpath = sourceSets.main.runtimeClasspath
191+
mainClass = 'org.confluence.lib.util.lang.LangDistinctor'
184192
args "../"
185193
}

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ minecraft_version=1.21.1
1313
# as they do not follow standard versioning conventions.
1414
minecraft_version_range=[1.21.1,1.22)
1515
# The Neo version must agree with the Minecraft version to get a valid artifact
16-
neo_version=21.1.209
16+
neo_version=21.1.218
1717
# The Neo version range can use any version of Neo as bounds
1818
neo_version_range=[21,)
1919
# The loader version range can only use the major version of FML as bounds
@@ -30,7 +30,7 @@ mod_name=Confluence Magic Lib
3030
mod_license=MIT
3131
# The mod version. See https://semver.org/
3232
###### remove '-SNAPSHOT' when merge to main branch ######
33-
mod_version=0.0.2f-SNAPSHOT
33+
mod_version=0.0.6
3434
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
3535
# This should match the base package used for the mod sources.
3636
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html

src/main/java/org/confluence/lib/ConfluenceMagicLib.java

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import net.neoforged.fml.ModContainer;
1717
import net.neoforged.fml.ModList;
1818
import net.neoforged.fml.common.Mod;
19+
import net.neoforged.neoforge.attachment.AttachmentType;
1920
import net.neoforged.neoforge.common.crafting.IngredientType;
2021
import net.neoforged.neoforge.registries.DeferredHolder;
2122
import net.neoforged.neoforge.registries.DeferredRegister;
@@ -27,31 +28,32 @@
2728
import org.confluence.lib.common.recipe.AmountIngredient;
2829
import org.confluence.lib.common.worldgen.structure.GridPiece;
2930
import org.confluence.lib.common.worldgen.structure.SimpleTemplatePiece;
30-
import org.confluence.lib.util.NaturalSpawnerUtil;
31-
import org.jetbrains.annotations.ApiStatus;
31+
import org.confluence.lib.util.DelayTaskHolder;
3232
import org.jetbrains.annotations.NotNull;
3333
import org.slf4j.Logger;
3434
import org.slf4j.LoggerFactory;
3535

3636
import java.util.function.Supplier;
3737

3838
@Mod(ConfluenceMagicLib.LIB_ID)
39-
public class ConfluenceMagicLib {
39+
public final class ConfluenceMagicLib {
4040
public static final String LIB_ID = "confluence_magic_lib";
4141
public static final String CONFLUENCE_ID = "confluence";
4242
public static final Logger LOGGER = LoggerFactory.getLogger("Confluence Magic Lib");
4343
public static final Supplier<Boolean> IS_CONFLUENCE_LOADED = Suppliers.memoize(() -> ModList.get().isLoaded(CONFLUENCE_ID));
4444

45+
//region 数据附件
46+
private static final DeferredRegister<AttachmentType<?>> ATTACHMENT_TYPE = DeferredRegister.create(NeoForgeRegistries.ATTACHMENT_TYPES, LIB_ID);
47+
48+
public static final Supplier<AttachmentType<DelayTaskHolder>> DELAY_TASK_HOLDER = ATTACHMENT_TYPE.register("delay_task_holder", () -> AttachmentType.builder(DelayTaskHolder::new).build());
49+
//endregion
50+
4551
// region 属性
4652
private static final DeferredRegister<Attribute> ATTRIBUTES = DeferredRegister.create(Registries.ATTRIBUTE, LIB_ID);
47-
/**
48-
* 玩家怪物生成速度系数
49-
*/
50-
public static final DeferredHolder<Attribute, RangedAttribute> MOB_SPAWN_SPEED_MULTIPLIER = registerRangedAttribute("player.mob_spawn_speed_multiplier", NaturalSpawnerUtil.DEFAULT_MULTIPLIER, 0, 1024, false, Attribute.Sentiment.NEUTRAL);
51-
/**
52-
* 玩家怪物生成数量系数
53-
*/
54-
public static final DeferredHolder<Attribute, RangedAttribute> MOB_SPAWN_COUNT_MULTIPLIER = registerRangedAttribute("player.mob_spawn_count_multiplier", NaturalSpawnerUtil.DEFAULT_MULTIPLIER, 0, 1024, false, Attribute.Sentiment.NEUTRAL);
53+
/// 玩家怪物生成速度系数
54+
public static final DeferredHolder<Attribute, RangedAttribute> MOB_SPAWN_SPEED_MULTIPLIER = registerRangedAttribute("player.mob_spawn_speed_multiplier", 1, 0, 1024, false, Attribute.Sentiment.NEUTRAL);
55+
/// 玩家怪物生成数量系数
56+
public static final DeferredHolder<Attribute, RangedAttribute> MOB_SPAWN_COUNT_MULTIPLIER = registerRangedAttribute("player.mob_spawn_count_multiplier", 1, 0, 1024, false, Attribute.Sentiment.NEUTRAL);
5557

5658
private static DeferredHolder<Attribute, RangedAttribute> registerRangedAttribute(String name, double defaultValue, double min, double max, boolean syncable, Attribute.Sentiment sentiment) {
5759
return ATTRIBUTES.register(name, () -> {
@@ -99,6 +101,7 @@ public StreamCodec<? super RegistryFriendlyByteBuf, CrossDustParticleOptions> st
99101

100102
public ConfluenceMagicLib(IEventBus modEventBus, ModContainer modContainer) {
101103
StartupConfig.register(modContainer);
104+
ATTACHMENT_TYPE.register(modEventBus);
102105
ATTRIBUTES.register(modEventBus);
103106
INGREDIENT_TYPES.register(modEventBus);
104107
PIECE_TYPES.register(modEventBus);
@@ -109,10 +112,4 @@ public ConfluenceMagicLib(IEventBus modEventBus, ModContainer modContainer) {
109112
public static ResourceLocation asResource(String path) {
110113
return ResourceLocation.fromNamespaceAndPath(LIB_ID, path);
111114
}
112-
113-
@Deprecated(since = "1.2.0", forRemoval = true)
114-
@ApiStatus.ScheduledForRemoval(inVersion = "1.3.0")
115-
public static boolean isConfluenceLoaded() {
116-
return IS_CONFLUENCE_LOADED.get();
117-
}
118115
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package org.confluence.lib.api.entity;
2+
3+
import net.minecraft.ChatFormatting;
4+
import net.minecraft.network.chat.Component;
5+
import net.minecraft.server.level.ServerLevel;
6+
import net.minecraft.world.entity.Entity;
7+
import net.minecraft.world.entity.monster.Enemy;
8+
import net.minecraft.world.entity.player.Player;
9+
import net.minecraft.world.level.Level;
10+
import org.apache.commons.lang3.stream.Streams;
11+
import org.confluence.lib.color.GlobalColors;
12+
13+
/// All bosses should implement this interface
14+
///
15+
/// 所有boss都应该实现这个接口
16+
public interface Boss extends Enemy, IDiscardWhenRespawnEntity {
17+
default boolean shouldShowMessage() {
18+
return isMainBody();
19+
}
20+
21+
default boolean isMainBody() {
22+
return true;
23+
}
24+
25+
default boolean shouldEnhanceMultiplayer() {
26+
return true;
27+
}
28+
29+
interface BossPart extends Boss {
30+
@Override
31+
default boolean isMainBody() {
32+
return false;
33+
}
34+
}
35+
36+
static void sendBossSpawnMessage(Entity entity) {
37+
Level level = entity.level();
38+
if (!level.isClientSide && entity instanceof Boss boss) {
39+
if (boss.shouldShowMessage()) {
40+
Component mes = Component.translatable("message.confluence.boss_spawn",
41+
entity.getDisplayName()).withColor(GlobalColors.EVENT.get()).withStyle(ChatFormatting.BOLD);
42+
43+
for (Player player : level.players()) {
44+
player.sendSystemMessage(mes);
45+
}
46+
}
47+
}
48+
}
49+
50+
static void sendBossDeathMessage(Entity entity) {
51+
Level level = entity.level();
52+
if (!level.isClientSide && entity instanceof Boss boss) {
53+
if (boss.shouldShowMessage()) {
54+
Component mes = Component.translatable("message.confluence.boss_leave",
55+
entity.getDisplayName()).withColor(GlobalColors.EVENT.get()).withStyle(ChatFormatting.BOLD);
56+
57+
for (Player player : level.players()) {
58+
player.sendSystemMessage(mes);
59+
}
60+
}
61+
}
62+
}
63+
64+
static boolean noBossInWorld(ServerLevel level) {
65+
return Streams.of(level.getAllEntities()).noneMatch(entity -> entity instanceof Boss);
66+
}
67+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.confluence.lib.api.entity;
2+
3+
import net.minecraft.server.level.ServerPlayer;
4+
import net.minecraft.world.entity.Entity;
5+
import net.minecraft.world.entity.player.Player;
6+
7+
import java.util.List;
8+
9+
/// 当玩家重生时,若附近没有存活的玩家,实现该接口的实体会消失,以实现出生保护
10+
public interface IDiscardWhenRespawnEntity {
11+
default boolean shouldDiscard(boolean hasNearbyPlayer) {
12+
return !hasNearbyPlayer;
13+
}
14+
15+
static void process(ServerPlayer player) {
16+
List<Entity> entities = player.level().getEntities(player, player.getBoundingBox().inflate(32));
17+
boolean hasPlayer = entities.stream().anyMatch(e -> e instanceof Player);
18+
entities.stream().filter(e -> e instanceof IDiscardWhenRespawnEntity entity && entity.shouldDiscard(hasPlayer)).forEach(Entity::discard);
19+
}
20+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package org.confluence.lib.client;
2+
3+
public final class DPSMeter {
4+
private static boolean dpsStarted;
5+
private static long dpsLastHit;
6+
private static float dpsDamage;
7+
private static long dpsStart;
8+
private static long dpsEnd;
9+
10+
public static void addDPS(float dmg, long currentTime) {
11+
if (dpsStarted) {
12+
dpsLastHit = currentTime;
13+
dpsDamage += dmg;
14+
dpsEnd = currentTime;
15+
} else {
16+
dpsStarted = true;
17+
dpsStart = currentTime;
18+
dpsEnd = currentTime;
19+
dpsLastHit = currentTime;
20+
dpsDamage = dmg;
21+
}
22+
}
23+
24+
public static void checkDPSTime(long currentTime) {
25+
if (dpsStarted && currentTime - dpsLastHit >= 30) {
26+
dpsStarted = false;
27+
}
28+
}
29+
30+
public static float getDPS(long currentTime) {
31+
float num = (dpsEnd - dpsStart) / 20.0F;
32+
if (num >= 3.0F) {
33+
dpsStart = currentTime - 20;
34+
dpsDamage = dpsDamage / num;
35+
num = (dpsEnd - dpsStart) / 20.0F;
36+
}
37+
if (num < 1.0F) num = 1.0F;
38+
return dpsDamage / num;
39+
}
40+
}

src/main/java/org/confluence/lib/client/event/LibGameEvents.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.mojang.datafixers.util.Either;
44
import net.minecraft.ChatFormatting;
5+
import net.minecraft.client.Minecraft;
6+
import net.minecraft.client.player.LocalPlayer;
57
import net.minecraft.network.chat.Component;
68
import net.minecraft.network.chat.FormattedText;
79
import net.minecraft.world.inventory.tooltip.TooltipComponent;
@@ -13,6 +15,7 @@
1315
import net.neoforged.neoforge.client.event.ClientTickEvent;
1416
import net.neoforged.neoforge.client.event.RenderTooltipEvent;
1517
import org.confluence.lib.ConfluenceMagicLib;
18+
import org.confluence.lib.client.DPSMeter;
1619
import org.confluence.lib.client.animate.ExpertColorAnimation;
1720
import org.confluence.lib.client.animate.MasterColorAnimation;
1821
import org.confluence.lib.common.LibTags;
@@ -27,6 +30,10 @@ public final class LibGameEvents {
2730
public static void clientTick$Post(ClientTickEvent.Pre event) {
2831
ExpertColorAnimation.INSTANCE.updateColor();
2932
MasterColorAnimation.INSTANCE.updateColor();
33+
LocalPlayer player = Minecraft.getInstance().player;
34+
if (player != null) {
35+
DPSMeter.checkDPSTime(player.level().getGameTime());
36+
}
3037
}
3138

3239
@SubscribeEvent(priority = EventPriority.HIGHEST)

src/main/java/org/confluence/lib/client/event/LibModEvents.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
@EventBusSubscriber(modid = ConfluenceMagicLib.LIB_ID, value = Dist.CLIENT)
1111
public final class LibModEvents {
1212
@SubscribeEvent
13-
public static void registerParticles(RegisterParticleProvidersEvent event) {
13+
public static void registerParticleProviders(RegisterParticleProvidersEvent event) {
1414
event.registerSpriteSet(ConfluenceMagicLib.CROSS_DUST_PARTICLE.get(), CrossDustParticle.Provider::new);
1515
}
1616
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package org.confluence.lib.client.render.item;
2+
3+
import com.mojang.blaze3d.vertex.PoseStack;
4+
import net.minecraft.client.Minecraft;
5+
import net.minecraft.client.model.HumanoidModel;
6+
import net.minecraft.client.player.LocalPlayer;
7+
import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer;
8+
import net.minecraft.client.renderer.MultiBufferSource;
9+
import net.minecraft.client.renderer.Sheets;
10+
import net.minecraft.client.renderer.entity.ItemRenderer;
11+
import net.minecraft.world.InteractionHand;
12+
import net.minecraft.world.entity.HumanoidArm;
13+
import net.minecraft.world.entity.LivingEntity;
14+
import net.minecraft.world.item.ItemDisplayContext;
15+
import net.minecraft.world.item.ItemStack;
16+
import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions;
17+
import org.jetbrains.annotations.Nullable;
18+
19+
public class SimpleClientItemExtensions implements IClientItemExtensions {
20+
protected RenderByItemCallback renderByItemCallback = (minecraft, stack, displayContext, poseStack, buffer, packedLight, packedOverlay) -> renderSimpleItem(minecraft, stack, poseStack, buffer, packedLight, packedOverlay);
21+
protected BlockEntityWithoutLevelRenderer renderer;
22+
protected HandTransformPredicate handTransformPredicate = IClientItemExtensions.super::applyForgeHandTransform;
23+
protected ArmPoseGetter armPoseGetter = IClientItemExtensions.super::getArmPose;
24+
25+
public SimpleClientItemExtensions noRenderer() {
26+
this.renderByItemCallback = (minecraft, stack, displayContext, poseStack, buffer, packedLight, packedOverlay) -> {};
27+
return this;
28+
}
29+
30+
public SimpleClientItemExtensions customRenderer(RenderByItemCallback callback) {
31+
this.renderByItemCallback = callback;
32+
return this;
33+
}
34+
35+
public SimpleClientItemExtensions handTransform(boolean force) {
36+
this.handTransformPredicate = (poseStack, player, arm, itemInHand, partialTick, equipProcess, swingProcess) -> force;
37+
return this;
38+
}
39+
40+
public SimpleClientItemExtensions handTransform(HandTransformPredicate predicate) {
41+
this.handTransformPredicate = predicate;
42+
return this;
43+
}
44+
45+
public SimpleClientItemExtensions armPose(HumanoidModel.ArmPose armPose) {
46+
this.armPoseGetter = (living, hand, itemStack) -> armPose;
47+
return this;
48+
}
49+
50+
public SimpleClientItemExtensions armPose(ArmPoseGetter getter) {
51+
this.armPoseGetter = getter;
52+
return this;
53+
}
54+
55+
@Override
56+
public BlockEntityWithoutLevelRenderer getCustomRenderer() {
57+
if (renderer == null) {
58+
Minecraft minecraft = Minecraft.getInstance();
59+
this.renderer = new BlockEntityWithoutLevelRenderer(minecraft.getBlockEntityRenderDispatcher(), minecraft.getEntityModels()) {
60+
@Override
61+
public void renderByItem(ItemStack stack, ItemDisplayContext displayContext, PoseStack poseStack, MultiBufferSource buffer, int packedLight, int packedOverlay) {
62+
renderByItemCallback.render(minecraft, stack, displayContext, poseStack, buffer, packedLight, packedOverlay);
63+
}
64+
};
65+
}
66+
return renderer;
67+
}
68+
69+
@Override
70+
public boolean applyForgeHandTransform(PoseStack poseStack, LocalPlayer player, HumanoidArm arm, ItemStack itemInHand, float partialTick, float equipProcess, float swingProcess) {
71+
return handTransformPredicate.force(poseStack, player, arm, itemInHand, partialTick, equipProcess, swingProcess);
72+
}
73+
74+
@Override
75+
public HumanoidModel.@Nullable ArmPose getArmPose(LivingEntity entityLiving, InteractionHand hand, ItemStack itemStack) {
76+
return armPoseGetter.get(entityLiving, hand, itemStack);
77+
}
78+
79+
public static void renderSimpleItem(Minecraft minecraft, ItemStack stack, PoseStack poseStack, MultiBufferSource buffer, int packedLight, int packedOverlay) {
80+
minecraft.getItemRenderer().renderModelLists(
81+
minecraft.getItemRenderer().getModel(stack, minecraft.level, null, 260109),
82+
stack, packedLight, packedOverlay, poseStack,
83+
ItemRenderer.getFoilBufferDirect(buffer, Sheets.translucentCullBlockSheet(), true, stack.hasFoil())
84+
);
85+
}
86+
87+
@FunctionalInterface
88+
public interface RenderByItemCallback {
89+
void render(Minecraft minecraft, ItemStack stack, ItemDisplayContext displayContext, PoseStack poseStack, MultiBufferSource buffer, int packedLight, int packedOverlay);
90+
}
91+
92+
@FunctionalInterface
93+
public interface HandTransformPredicate {
94+
boolean force(PoseStack poseStack, LocalPlayer player, HumanoidArm arm, ItemStack itemInHand, float partialTick, float equipProcess, float swingProcess);
95+
}
96+
97+
@FunctionalInterface
98+
public interface ArmPoseGetter {
99+
@Nullable HumanoidModel.ArmPose get(LivingEntity living, InteractionHand hand, ItemStack itemStack);
100+
}
101+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@ParametersAreNonnullByDefault
2+
@MethodsReturnNonnullByDefault
3+
package org.confluence.lib.client.render.item;
4+
5+
import net.minecraft.MethodsReturnNonnullByDefault;
6+
7+
import javax.annotation.ParametersAreNonnullByDefault;

0 commit comments

Comments
 (0)