Celestria 2.0.0 - Improved Everything

- Port to 1.21
- Neoforge support
- Multiple shooting stars at the same time
- Stellar nights based on moon phase -> Increased shooting star rate
- Stars now move linearly instead of rotating
- Serverside-mode using Polymer
This commit is contained in:
Martin Prokoph
2024-08-17 21:20:41 +02:00
parent 541d4d164e
commit a42ffc8593
65 changed files with 1253 additions and 359 deletions

View File

@@ -1,82 +1,81 @@
plugins {
id 'fabric-loom' version '0.12-SNAPSHOT'
id 'maven-publish'
id "architectury-plugin" version "3.4-SNAPSHOT"
id "dev.architectury.loom" version "1.6-SNAPSHOT" apply false
id "me.shedaniel.unified-publishing" version "0.1.+" apply false
id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
}
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
archivesBaseName = project.archives_base_name
version = project.mod_version
group = project.maven_group
architectury {
minecraft = rootProject.minecraft_version
}
repositories {
maven { url "https://api.modrinth.com/maven" }
}
dependencies {
//to change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
modImplementation "maven.modrinth:midnightlib:${midnightlib_version}"
include "maven.modrinth:midnightlib:${midnightlib_version}"
}
processResources {
inputs.property "version", project.version
filesMatching("fabric.mod.json") {
expand "version": project.version
maven {
url = "https://api.modrinth.com/maven"
}
}
tasks.withType(JavaCompile).configureEach {
// ensure that the encoding is set to UTF-8, no matter what the system default is
// this fixes some edge cases with special characters not displaying correctly
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
// If Javadoc is generated, this must be specified in that task too.
it.options.encoding = "UTF-8"
subprojects {
apply plugin: "dev.architectury.loom"
repositories {
maven {
url = "https://api.modrinth.com/maven"
}
maven { url 'https://jitpack.io' }
maven { url 'https://maven.nucleoid.xyz' }
}
// Minecraft 1.17 (21w19a) upwards uses Java 16.
it.options.release = 17
}
java {
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
// if it is present.
// If you remove this line, sources will not be generated.
withSourcesJar()
}
jar {
from("LICENSE") {
rename { "${it}_${project.archivesBaseName}"}
dependencies {
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
// The following line declares the mojmap mappings, you may use other mappings as well
//mappings loom.officialMojangMappings()
// The following line declares the yarn mappings you may select this one as well.
mappings loom.layered {
it.mappings("net.fabricmc:yarn:$rootProject.yarn_mappings:v2")
it.mappings("dev.architectury:yarn-mappings-patch-neoforge:$rootProject.yarn_mappings_patch_neoforge_version")
}
}
}
// configure the maven publication
publishing {
publications {
mavenJava(MavenPublication) {
// add all the jars that should be included when publishing to maven
artifact(remapJar) {
builtBy remapJar
}
artifact(sourcesJar) {
builtBy remapSourcesJar
allprojects {
apply plugin: "java"
apply plugin: "architectury-plugin"
apply plugin: "maven-publish"
archivesBaseName = rootProject.archives_base_name
version = rootProject.mod_version
group = rootProject.maven_group
repositories {
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
}
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
options.release = 21
}
ext {
releaseChangelog = {
def changes = new StringBuilder()
changes << "## Celestria v$project.version for $project.minecraft_version\n[View the changelog](https://www.github.com/TeamMidnightDust/Celestria/commits/)"
def proc = "git log --max-count=1 --pretty=format:%s".execute()
proc.in.eachLine { line ->
def processedLine = line.toString()
if (!processedLine.contains("New translations") && !processedLine.contains("Merge") && !processedLine.contains("branch")) {
changes << "\n- ${processedLine.capitalize()}"
}
}
proc.waitFor()
return changes.toString()
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
java {
withSourcesJar()
}
}
}

26
common/build.gradle Normal file
View File

@@ -0,0 +1,26 @@
architectury {
common(rootProject.enabled_platforms.split(","))
}
dependencies {
// We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies
// Do NOT use other classes from fabric loader
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
// Using the Fabric version of midnightlib here to create a common config and get useful utilities
// Just make sure NOT to use classes from the .fabric classpath
modCompileOnlyApi "maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric"
}
publishing {
publications {
mavenCommon(MavenPublication) {
artifactId = rootProject.archives_base_name
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
}
}

View File

@@ -0,0 +1,107 @@
package eu.midnightdust.celestria;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import eu.midnightdust.celestria.effect.StatusEffectInit;
import eu.midnightdust.celestria.util.CommonUtils;
import eu.midnightdust.celestria.util.PacketUtils;
import eu.midnightdust.celestria.util.ShootingStarPayload;
import eu.midnightdust.celestria.util.WelcomePayload;
import eu.midnightdust.celestria.config.CelestriaConfig;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.minecraft.command.argument.EntityArgumentType;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Celestria {
public static final String MOD_ID = "celestria";
public static final Random random = Random.create();
private static int prevPlayerAmount = 0;
public static final List<PlayerEntity> playersWithMod = new ArrayList<>();
public static void init() {
CelestriaConfig.init(MOD_ID, CelestriaConfig.class);
if (CelestriaConfig.enableInsomnia || PlatformFunctions.isClientEnv()) StatusEffectInit.init();
PacketUtils.registerPayloadCommon(WelcomePayload.PACKET_ID, WelcomePayload.codec);
PacketUtils.registerPayloadS2C(ShootingStarPayload.PACKET_ID, ShootingStarPayload.codec);
PacketUtils.registerServerGlobalReceiver(WelcomePayload.PACKET_ID, (payload, player) -> playersWithMod.add(player));
LiteralArgumentBuilder<ServerCommandSource> command = CommandManager.literal("shootingStar")
.then(CommandManager.argument("players", EntityArgumentType.players()).requires(source -> source.hasPermissionLevel(2)).executes(ctx ->
createShootingStar(random.nextBetween(100, 150),
random.nextInt(360),
random.nextInt(3),
random.nextBetween(10, 170),
random.nextBetween(Math.min(CelestriaConfig.shootingStarMinSize, CelestriaConfig.shootingStarMaxSize),
Math.max(CelestriaConfig.shootingStarMaxSize, CelestriaConfig.shootingStarMinSize)),
EntityArgumentType.getPlayers(ctx, "players").toArray(new ServerPlayerEntity[0])))
.then(CommandManager.argument("x", IntegerArgumentType.integer(90, 180))
.then(CommandManager.argument("y", IntegerArgumentType.integer(0, 360))
.then(CommandManager.argument("type", IntegerArgumentType.integer(0, 3))
.then(CommandManager.argument("rotation", IntegerArgumentType.integer(10, 170))
.then(CommandManager.argument("size", IntegerArgumentType.integer(1, 250))
.requires(source -> source.hasPermissionLevel(2)).executes(ctx -> createShootingStar(
IntegerArgumentType.getInteger(ctx, "x"),
IntegerArgumentType.getInteger(ctx, "y"),
IntegerArgumentType.getInteger(ctx, "type"),
IntegerArgumentType.getInteger(ctx, "rotation"),
IntegerArgumentType.getInteger(ctx, "size"),
EntityArgumentType.getPlayers(ctx, "players").toArray(new ServerPlayerEntity[0])))))))));
LiteralArgumentBuilder<ServerCommandSource> finalized = CommandManager.literal("celestria").then(command).requires(source -> source.hasPermissionLevel(2));
PlatformFunctions.registerCommand(finalized);
CommonUtils.registerWorldTickEvent(true, world -> {
if (world.getPlayers().size() > prevPlayerAmount && CelestriaConfig.enableShootingStars) {
playersWithMod.clear();
world.getPlayers().forEach(player -> PacketUtils.sendPlayPayloadS2C((ServerPlayerEntity) player, new WelcomePayload()));
prevPlayerAmount = world.getPlayers().size();
}
if (world.isNight() && CelestriaConfig.enableInsomnia && world.getMoonPhase() == 0) {
for (PlayerEntity player : world.getPlayers()) {
if (world.random.nextInt(CelestriaConfig.insomniaChance) == 0) {
player.addStatusEffect(StatusEffectInit.insomniaEffect());
}
}
}
if (world.isNight() && CelestriaConfig.enableShootingStars && world.random.nextInt(getChance(world)) == 0) {
int x = world.random.nextBetween(100, 150);
int y = world.random.nextInt(360);
int type = world.random.nextInt(3);
int rotation = world.random.nextBetween(10, 170);
int size = world.random.nextBetween(Math.min(CelestriaConfig.shootingStarMinSize, CelestriaConfig.shootingStarMaxSize), Math.max(CelestriaConfig.shootingStarMaxSize, CelestriaConfig.shootingStarMinSize));
createShootingStar(x, y, type, rotation, size, playersWithMod.toArray(new ServerPlayerEntity[0]));
}
});
}
public static int createShootingStar(int x, int y, int type, int rotation, int size, ServerPlayerEntity... players) {
int message = Random.create().nextInt(CelestriaConfig.shootingStarMessages.size());
Arrays.stream(players).forEach(player -> {
player.addStatusEffect(new StatusEffectInstance(StatusEffects.LUCK, CelestriaConfig.shootingStarLuckDuration, 0, true, false, true));
PacketUtils.sendPlayPayloadS2C(player, new ShootingStarPayload(x, y, type, rotation, size));
if (CelestriaConfig.sendChatMessages) player.sendMessageToClient(Text.translatable(CelestriaConfig.shootingStarMessages.get(message)),true);
});
return 1;
}
public static int getChance(World world) {
// Stellar nights will occur when the moon is in the waxing crescent phase
return (world.getMoonPhase() == 5) ? CelestriaConfig.shootingStarChance / 200 : CelestriaConfig.shootingStarChance;
}
public static Identifier id(String path) {
return Identifier.of(MOD_ID, path);
}
}

View File

@@ -0,0 +1,44 @@
package eu.midnightdust.celestria;
import eu.midnightdust.celestria.config.CelestriaConfig;
import eu.midnightdust.celestria.util.ClientUtils;
import eu.midnightdust.celestria.util.PacketUtils;
import eu.midnightdust.celestria.util.ShootingStarPayload;
import eu.midnightdust.celestria.util.WelcomePayload;
import java.util.HashSet;
import java.util.Set;
import static eu.midnightdust.celestria.Celestria.id;
import static eu.midnightdust.celestria.Celestria.random;
public class CelestriaClient {
private static boolean clientOnlyMode = true;
public static Set<ShootingStar> shootingStars = new HashSet<>();
public static void init() {
ClientUtils.registerBuiltinResourcePack(id("realistic"));
ClientUtils.registerBuiltinResourcePack(id("pixelperfect"));
PacketUtils.registerClientGlobalReceiver(WelcomePayload.PACKET_ID,
(payload, player) -> {
PacketUtils.sendPlayPayloadC2S(payload);
CelestriaClient.clientOnlyMode = false;
});
PacketUtils.registerClientGlobalReceiver(ShootingStarPayload.PACKET_ID,
(payload, player) -> {
CelestriaClient.clientOnlyMode = false; // If the welcome packet wasn't received correctly for some reason, disable clientOnlyMode on shooting star occurrence
shootingStars.add(new ShootingStar(CelestriaConfig.shootingStarPathLength, payload.type(), payload.x(), payload.y(), payload.rotation(), payload.size()));
});
ClientUtils.registerClientTick(true, (client) -> {
shootingStars.forEach(ShootingStar::tick);
shootingStars.removeAll(shootingStars.stream().filter(star -> star.progress <= 0).toList());
if (CelestriaClient.clientOnlyMode && CelestriaConfig.enableShootingStars && client.world != null) {
float tickDelta = client.getRenderTickCounter().getTickDelta(true);
if ((180 < client.world.getSkyAngle(tickDelta) * 360 && 270 > client.world.getSkyAngle(tickDelta) * 360) && random.nextInt(Celestria.getChance(client.world)) == 0) {
shootingStars.add(new ShootingStar(CelestriaConfig.shootingStarPathLength, random.nextInt(3), random.nextBetween(100, 150), random.nextInt(360), random.nextBetween(10, 170), random.nextBetween(Math.min(CelestriaConfig.shootingStarMinSize, CelestriaConfig.shootingStarMaxSize), Math.max(CelestriaConfig.shootingStarMaxSize, CelestriaConfig.shootingStarMinSize))));
}
}
});
ClientUtils.registerDisconnectEvent((handler, client) -> CelestriaClient.clientOnlyMode = true);
}
}

View File

@@ -0,0 +1,18 @@
package eu.midnightdust.celestria;
public class ShootingStar {
public int progress;
public final int type, x, y, rotation, size;
public ShootingStar(int progress, int type, int x, int y, int rotation, int size) {
this.progress = progress;
this.type = type;
this.x = x;
this.y = y;
this.rotation = rotation;
this.size = size;
}
public void tick() {
--progress;
}
}

View File

@@ -0,0 +1,25 @@
package eu.midnightdust.celestria.config;
import com.google.common.collect.Lists;
import eu.midnightdust.lib.config.MidnightConfig;
import java.util.List;
public class CelestriaConfig extends MidnightConfig {
public static final String STARS = "stars";
public static final String INSOMNIA = "insomnia";
@Entry public static boolean sendChatMessages = true;
@Entry(category = STARS) public static boolean enableShootingStars = true;
@Entry(category = STARS, isSlider = true, min = 0f, max = 6f) public static float shootingStarDistance = 2f;
@Entry(category = STARS, isSlider = true, min = 1, max = 250) public static int shootingStarMinSize = 25;
@Entry(category = STARS, isSlider = true, min = 1, max = 250) public static int shootingStarMaxSize = 125;
@Entry(category = STARS, isSlider = true, min = 0f, max = 10f) public static float shootingStarSpeed = 6.0f;
@Entry(category = STARS, isSlider = true, min = 0, max = 500) public static int shootingStarPathLength = 50;
@Entry(category = STARS) public static int shootingStarChance = 20000;
@Entry(category = STARS) public static int shootingStarLuckDuration = 1000;
@Entry(category = STARS) public static List<String> shootingStarMessages = Lists.newArrayList("celestria.shootingStar.1", "celestria.shootingStar.2", "celestria.shootingStar.3");
@Entry(category = INSOMNIA) public static boolean enableInsomnia = true;
@Entry(category = INSOMNIA) public static int insomniaChance = 30000;
@Entry(category = INSOMNIA, isSlider = true, min = 0, max = 5000) public static int insomniaDuration = 1000;
@Entry(category = INSOMNIA) public static List<String> insomniaMessages = Lists.newArrayList("celestria.insomnia.1", "celestria.insomnia.2");
}

View File

@@ -0,0 +1,33 @@
package eu.midnightdust.celestria.effect;
import eu.midnightdust.celestria.config.CelestriaConfig;
import eu.midnightdust.celestria.util.PolymerUtils;
import eu.midnightdust.lib.util.MidnightColorUtil;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectCategory;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.entry.RegistryEntry;
import static eu.midnightdust.celestria.Celestria.id;
public class StatusEffectInit {
public static final StatusEffect INSOMNIA = initInsomnia();
public static RegistryEntry<StatusEffect> INSOMNIA_EFFECT;
public static void init() {
if (!PlatformFunctions.getPlatformName().equals("neoforge")) {
Registry.register(Registries.STATUS_EFFECT, id("insomnia"), INSOMNIA);
INSOMNIA_EFFECT = Registries.STATUS_EFFECT.getEntry(INSOMNIA);
}
}
public static StatusEffectInstance insomniaEffect() {
return new StatusEffectInstance(INSOMNIA_EFFECT, CelestriaConfig.insomniaDuration, 0, true, false, true);
}
public static StatusEffect initInsomnia() {
if (PlatformFunctions.isModLoaded("polymer-core")) return PolymerUtils.initInsomnia();
else return new InsomniaStatusEffect(StatusEffectCategory.HARMFUL, MidnightColorUtil.hex2Rgb("88A9C8").getRGB());
}
}

View File

@@ -1,14 +1,13 @@
package eu.midnightdust.celestria.mixin;
import eu.midnightdust.celestria.Celestria;
import eu.midnightdust.celestria.config.CelestriaConfig;
import eu.midnightdust.celestria.effect.StatusEffectInit;
import net.minecraft.block.BedBlock;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@@ -20,8 +19,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BedBlock.class)
public abstract class MixinBedBlock {
@Inject(at = @At("HEAD"), method = "onUse", cancellable = true)
public void celestria$onBedUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable<ActionResult> cir) {
if (!world.isClient() && player instanceof ServerPlayerEntity serverPlayer && player.hasStatusEffect(Celestria.INSOMNIA)) {
public void celestria$onBedUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit, CallbackInfoReturnable<ActionResult> cir) {
if (CelestriaConfig.enableInsomnia && !world.isClient() && player instanceof ServerPlayerEntity serverPlayer && player.hasStatusEffect(StatusEffectInit.INSOMNIA_EFFECT)) {
if (CelestriaConfig.sendChatMessages) serverPlayer.sendMessageToClient(Text.literal("§f§l[§7§lC§8§le§7§ll§f§le§7§ls§8§lt§7§lr§f§li§7§la§8§l] ").append(Text.translatable(CelestriaConfig.insomniaMessages.get(world.random.nextInt(CelestriaConfig.insomniaMessages.size())))),false);
cir.setReturnValue(ActionResult.CONSUME);
}

View File

@@ -0,0 +1,28 @@
package eu.midnightdust.celestria.mixin;
import eu.midnightdust.celestria.render.ShootingStarRenderer;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.world.ClientWorld;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(WorldRenderer.class)
public abstract class MixinWorldRenderer {
@Unique private final ShootingStarRenderer celestria$shootingStarRenderer = new ShootingStarRenderer();
@Shadow @Nullable private ClientWorld world;
@Inject(at = @At(value = "TAIL"), method = "renderSky(Lorg/joml/Matrix4f;Lorg/joml/Matrix4f;FLnet/minecraft/client/render/Camera;ZLjava/lang/Runnable;)V")
public void celestria$renderShootingStars(Matrix4f matrix4f, Matrix4f projectionMatrix, float tickDelta, Camera camera, boolean thickFog, Runnable fogCallback, CallbackInfo ci) {
MatrixStack matrices = new MatrixStack();
matrices.multiplyPositionMatrix(matrix4f);
celestria$shootingStarRenderer.renderShootingStars(world, matrices);
}
}

View File

@@ -0,0 +1,62 @@
package eu.midnightdust.celestria.render;
import com.mojang.blaze3d.systems.RenderSystem;
import eu.midnightdust.celestria.CelestriaClient;
import eu.midnightdust.celestria.ShootingStar;
import eu.midnightdust.celestria.config.CelestriaConfig;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.BufferRenderer;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.util.math.RotationAxis;
import org.joml.Matrix4f;
import static eu.midnightdust.celestria.Celestria.id;
import static java.lang.Math.pow;
public class ShootingStarRenderer {
public void renderShootingStars(ClientWorld world, MatrixStack matrices) {
if (world != null && CelestriaConfig.enableShootingStars && !CelestriaClient.shootingStars.isEmpty()) {
world.getProfiler().swap("shooting_stars");
RenderSystem.defaultBlendFunc();
RenderSystem.enableDepthTest();
RenderSystem.enableBlend();
RenderSystem.setShader(GameRenderer::getPositionTexColorProgram);
CelestriaClient.shootingStars.forEach(star -> renderShootingStar(world, matrices, star));
RenderSystem.disableBlend();
RenderSystem.disableDepthTest();
}
}
@SuppressWarnings("SuspiciousNameCombination")
private void renderShootingStar(ClientWorld world, MatrixStack matrices, ShootingStar star) {
if (world != null && CelestriaConfig.enableShootingStars && !CelestriaClient.shootingStars.isEmpty()) {
world.getProfiler().swap("shooting_stars");
float alpha = (float) Math.clamp((star.progress - pow(1f / star.progress, 4)) / CelestriaConfig.shootingStarPathLength, 0, 1);
matrices.push();
matrices.scale(CelestriaConfig.shootingStarDistance,CelestriaConfig.shootingStarDistance,CelestriaConfig.shootingStarDistance);
int direction = isEven(star.type) ? -1 : 1;
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(star.y));
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(star.rotation * direction));
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(star.x+(star.progress*CelestriaConfig.shootingStarSpeed*0.05f)));
matrices.translate(star.progress * CelestriaConfig.shootingStarSpeed * direction, 0, 0);
Matrix4f matrix4f = matrices.peek().getPositionMatrix();
RenderSystem.setShaderTexture(0, id("textures/environment/shooting_star"+(star.type+1)+".png"));
BufferBuilder bufferBuilder = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
float height = star.size / 100f * 20.0F;
float width = star.size / 100f * 100.0F;
bufferBuilder.vertex(matrix4f, -height, -width, height).texture(0.0F, 0.0F).color(1, 1, 1, alpha);
bufferBuilder.vertex(matrix4f, height, -width, height).texture(1.0F, 0.0F).color(1, 1, 1, alpha);
bufferBuilder.vertex(matrix4f, height, -width, -height).texture(1.0F, 1.0F).color(1, 1, 1, alpha);
bufferBuilder.vertex(matrix4f, -height, -width, -height).texture(0.0F, 1.0F).color(1, 1, 1, alpha);
BufferRenderer.drawWithGlobalProgram(bufferBuilder.end());
matrices.pop();
}
}
public static boolean isEven(int i) {
return (i | 1) > i;
}
}

View File

@@ -0,0 +1,24 @@
package eu.midnightdust.celestria.util;
import dev.architectury.injectables.annotations.ExpectPlatform;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.util.Identifier;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
public class ClientUtils {
@ExpectPlatform
public static void registerBuiltinResourcePack(Identifier id) {
throw new AssertionError();
}
@ExpectPlatform
public static void registerClientTick(boolean endTick, Consumer<MinecraftClient> code) {
throw new AssertionError();
}
@ExpectPlatform
public static void registerDisconnectEvent(BiConsumer<ClientPlayNetworkHandler, MinecraftClient> function) {
throw new AssertionError();
}
}

View File

@@ -0,0 +1,13 @@
package eu.midnightdust.celestria.util;
import dev.architectury.injectables.annotations.ExpectPlatform;
import net.minecraft.world.World;
import java.util.function.Consumer;
public class CommonUtils {
@ExpectPlatform
public static void registerWorldTickEvent(boolean endTick, Consumer<World> code) {
throw new AssertionError();
}
}

View File

@@ -0,0 +1,47 @@
package eu.midnightdust.celestria.util;
import dev.architectury.injectables.annotations.ExpectPlatform;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.server.network.ServerPlayerEntity;
import java.util.function.BiConsumer;
public class PacketUtils {
// Common
@ExpectPlatform
public static <T extends CustomPayload> void registerPayloadCommon(CustomPayload.Id<T> id, PacketCodec<RegistryByteBuf, T> codec) {
throw new AssertionError();
}
// Server
@ExpectPlatform
public static <T extends CustomPayload> void registerPayloadS2C(CustomPayload.Id<T> id, PacketCodec<RegistryByteBuf, T> codec) {
throw new AssertionError();
}
@ExpectPlatform
public static void sendPlayPayloadS2C(ServerPlayerEntity player, CustomPayload payload) {
throw new AssertionError();
}
@ExpectPlatform
public static <T extends CustomPayload> void registerServerGlobalReceiver(CustomPayload.Id<T> id, BiConsumer<T, PlayerEntity> code) {
throw new AssertionError();
}
// Client
@ExpectPlatform
public static <T extends CustomPayload> void registerPayloadC2S(CustomPayload.Id<T> id, PacketCodec<RegistryByteBuf, T> codec) {
throw new AssertionError();
}
@ExpectPlatform
public static void sendPlayPayloadC2S(CustomPayload payload) {
throw new AssertionError();
}
@ExpectPlatform
public static <T extends CustomPayload> void registerClientGlobalReceiver(CustomPayload.Id<T> id, BiConsumer<T, PlayerEntity> code) {
throw new AssertionError();
}
}

View File

@@ -0,0 +1,11 @@
package eu.midnightdust.celestria.util;
import dev.architectury.injectables.annotations.ExpectPlatform;
import net.minecraft.entity.effect.StatusEffect;
public class PolymerUtils {
@ExpectPlatform
public static StatusEffect initInsomnia() {
throw new AssertionError();
}
}

View File

@@ -0,0 +1,24 @@
package eu.midnightdust.celestria.util;
import eu.midnightdust.celestria.Celestria;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.packet.CustomPayload;
public record ShootingStarPayload(int x, int y, int type, int rotation, int size) implements CustomPayload {
public static final CustomPayload.Id<ShootingStarPayload> PACKET_ID = new CustomPayload.Id<>(Celestria.id("shooting_star"));
public static final PacketCodec<RegistryByteBuf, ShootingStarPayload> codec = PacketCodec.of(ShootingStarPayload::write, ShootingStarPayload::read);
public static ShootingStarPayload read(RegistryByteBuf buf) {
return new ShootingStarPayload(buf.readInt(), buf.readInt(), buf.readInt(), buf.readInt(), buf.readInt());
}
public void write(RegistryByteBuf buf) {
buf.writeInt(x).writeInt(y).writeInt(type).writeInt(rotation).writeInt(size);
}
@Override
public CustomPayload.Id<? extends CustomPayload> getId() {
return PACKET_ID;
}
}

View File

@@ -0,0 +1,16 @@
package eu.midnightdust.celestria.util;
import eu.midnightdust.celestria.Celestria;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.packet.CustomPayload;
public record WelcomePayload() implements CustomPayload {
public static final CustomPayload.Id<WelcomePayload> PACKET_ID = new CustomPayload.Id<>(Celestria.id("welcome"));
public static final PacketCodec<RegistryByteBuf, WelcomePayload> codec = PacketCodec.of((a, b) -> {}, buf -> new WelcomePayload());
@Override
public Id<? extends CustomPayload> getId() {
return PACKET_ID;
}
}

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -1,12 +1,16 @@
{
"celestria.midnightconfig.title": "Celestria Konfiguration",
"celestria.midnightconfig.category.stars": "Sternschnuppen",
"celestria.midnightconfig.category.insomnia": "Schlaflosigkeit",
"celestria.midnightconfig.sendChatMessages": "Sende Chat Nachrichten bei Events",
"celestria.midnightconfig.enableShootingStars": "Aktiviere Sternschnuppen",
"celestria.midnightconfig.shootingStarScale": "Sternschnuppenskalierung",
"celestria.midnightconfig.shootingStarDistance": "Entfernung",
"celestria.midnightconfig.shootingStarDistance.tooltip": "Durch Anpassung der Entfernung kann die Kompatibilität mit Shadern verbessert werden.",
"celestria.midnightconfig.shootingStarMaxSize": "Maximale Größe",
"celestria.midnightconfig.shootingStarMinSize": "Minimale Größe",
"celestria.midnightconfig.shootingStarSpeed": "Sternschnuppengeschwindigkeit",
"celestria.midnightconfig.shootingStarPathLength": "Sternschnuppenpfadlänge",
"celestria.midnightconfig.shootingStarChance": "Sternschnuppen-Wahrscheinlichkeit",
"celestria.midnightconfig.shootingStarCooldownLength": "Sternschnuppen Cooldown Länge",
"celestria.midnightconfig.shootingStarLuckDuration": "Sternschnuppen Glück Effektlänge",
"celestria.midnightconfig.shootingStarMessages": "Sternschnuppen-Nachrichten",
"celestria.midnightconfig.enableInsomnia": "Aktiviere Schlaflosigkeit",
@@ -15,7 +19,7 @@
"celestria.midnightconfig.insomniaDuration": "Schlaflosigkeit Effektlänge",
"celestria.shootingStar.1": "§eOh, schau! Eine Sternschnuppe ist erschienen und hat dir Glück gebracht!",
"celestria.shootingStar.2": "§6Wow, eine Sternschnuppe ist erschienen, wünsch dir was!",
"celestria.shootingStar.3": "§2♪ Can we pretend that airplanes in the night sky are like shooting stars... ♫\n§3Oh warte, da ist ja eine echte Sternschnuppe!",
"celestria.shootingStar.3": "§2♪ Can we pretend that airplanes in the night sky are like shooting stars... ♫",
"celestria.insomnia.1": "§cDu hast Angst vor dem Vollmond, also kannst du einfach nicht einschlafen...",
"celestria.insomnia.2": "§3Ouuwwwh... Du hörst seltsame Geräusche und kannst deine Augen nicht schließen",
"effect.celestria.insomnia": "Schlaflosigkeit"

View File

@@ -0,0 +1,26 @@
{
"celestria.midnightconfig.title": "Celestria Config",
"celestria.midnightconfig.category.stars": "Shooting Stars",
"celestria.midnightconfig.category.insomnia": "Insomnia",
"celestria.midnightconfig.sendChatMessages": "Send Chat Messages on Events",
"celestria.midnightconfig.enableShootingStars": "Enable Shooting Stars",
"celestria.midnightconfig.shootingStarDistance": "Distance",
"celestria.midnightconfig.shootingStarDistance.tooltip": "Adjusting the distance can improve shader support",
"celestria.midnightconfig.shootingStarMaxSize": "Max Size",
"celestria.midnightconfig.shootingStarMinSize": "Min Size",
"celestria.midnightconfig.shootingStarSpeed": "Speed",
"celestria.midnightconfig.shootingStarPathLength": "Path Length",
"celestria.midnightconfig.shootingStarChance": "Chance",
"celestria.midnightconfig.shootingStarLuckDuration": "Luck Duration",
"celestria.midnightconfig.shootingStarMessages": "Messages",
"celestria.midnightconfig.enableInsomnia": "Enable Insomnia",
"celestria.midnightconfig.insomniaChance": "Chance",
"celestria.midnightconfig.insomniaMessages": "Messages",
"celestria.midnightconfig.insomniaDuration": "Insomnia Duration",
"celestria.shootingStar.1": "§eOh, look! A shooting star appeared and blessed you with good luck!",
"celestria.shootingStar.2": "§6Wow, a shooting star appeared, make a wish!",
"celestria.shootingStar.3": "§2♪ Can we pretend that airplanes in the night sky are like shooting stars... ♫",
"celestria.insomnia.1": "§cYou're afraid of the full moon, so you just can't find no rest...",
"celestria.insomnia.2": "§3Ouuwwwh... You hear strange noises from afar and can't close your eyes",
"effect.celestria.insomnia": "Insomnia"
}

View File

@@ -12,7 +12,7 @@
"celestria.midnightconfig.insomniaDuration": "Длительность Эффекта Бессонницы",
"celestria.shootingStar.1": "§eО, гляди! Появилась падающая звезда и благословила тебя удачей!",
"celestria.shootingStar.2": "§6Вау, появилась падающая звезда, загадай желание!",
"celestria.shootingStar.3": "§2♪ Можем ли мы представить, что самолеты в ночном небе походят на падающие звезды...... ♫\n§3О, погоди, это настоящая!",
"celestria.shootingStar.3": "§2♪ Можем ли мы представить, что самолеты в ночном небе походят на падающие звезды...... ♫",
"celestria.insomnia.1": "§cТы боишься полнолуния, поэтому не можешь найти себе покоя...",
"celestria.insomnia.2": "§3Ауууууууу... Ты слышишь странные звуки издалека и не можешь закрыть глаза",
"effect.celestria.insomnia": "Бессонница"

View File

@@ -1,6 +1,7 @@
{
"pack": {
"pack_format": 9,
"pack_format": 15,
"supported_formats": [15, 999],
"description": "Makes the shooting star texture consistent with vanilla stars"
}
}

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@@ -1,6 +1,7 @@
{
"pack": {
"pack_format": 9,
"pack_format": 15,
"supported_formats": [15, 999],
"description": "Makes the shooting star textures appear realistic"
}
}

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

103
fabric/build.gradle Normal file
View File

@@ -0,0 +1,103 @@
plugins {
id 'com.github.johnrengelman.shadow'
id "me.shedaniel.unified-publishing"
}
architectury {
platformSetupLoomIde()
fabric()
}
loom {
}
configurations {
common
shadowCommon // Don't use shadow from the shadow plugin since it *excludes* files.
compileClasspath.extendsFrom common
runtimeClasspath.extendsFrom common
developmentFabric.extendsFrom common
archivesBaseName = rootProject.archives_base_name + "-fabric"
}
dependencies {
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
modImplementation include ("maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric")
modImplementation ("eu.pb4:polymer-core:${polymer_version}")
common(project(path: ":common", configuration: "namedElements")) { transitive false }
shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false }
}
processResources {
inputs.property "version", project.version
filesMatching("fabric.mod.json") {
expand "version": project.version
}
}
shadowJar {
exclude "architectury.common.json"
configurations = [project.configurations.shadowCommon]
archiveClassifier = "dev-shadow"
}
remapJar {
input.set shadowJar.archiveFile
dependsOn shadowJar
}
sourcesJar {
def commonSources = project(":common").sourcesJar
dependsOn commonSources
from commonSources.archiveFile.map { zipTree(it) }
}
components.java {
withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
skip()
}
}
unifiedPublishing {
project {
displayName = "Celestria $project.version - Fabric $project.minecraft_version"
releaseType = "$project.release_type"
changelog = releaseChangelog()
gameVersions = []
gameLoaders = ["fabric","quilt"]
mainPublication remapJar
relations {
depends {
curseforge = "fabric-api"
modrinth = "fabric-api"
}
includes {
curseforge = "midnightlib"
modrinth = "midnightlib"
}
}
var CURSEFORGE_TOKEN = project.findProperty("CURSEFORGE_TOKEN") ?: System.getenv("CURSEFORGE_TOKEN")
if (CURSEFORGE_TOKEN != null) {
curseforge {
token = CURSEFORGE_TOKEN
id = rootProject.curseforge_id
gameVersions.addAll "Java 21", project.minecraft_version, project.supported_versions
}
}
var MODRINTH_TOKEN = project.findProperty("MODRINTH_TOKEN") ?: System.getenv("MODRINTH_TOKEN")
if (MODRINTH_TOKEN != null) {
modrinth {
token = MODRINTH_TOKEN
id = rootProject.modrinth_id
version = "$project.version-$project.name"
gameVersions.addAll project.minecraft_version, project.supported_versions
}
}
}
}

View File

@@ -0,0 +1,18 @@
package eu.midnightdust.celestria.fabric;
import eu.midnightdust.celestria.Celestria;
import eu.midnightdust.celestria.CelestriaClient;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.ModInitializer;
public class CelestriaFabric implements ModInitializer, ClientModInitializer {
@Override
public void onInitialize() {
Celestria.init();
}
@Override
public void onInitializeClient() {
CelestriaClient.init();
}
}

View File

@@ -0,0 +1,30 @@
package eu.midnightdust.celestria.util.fabric;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.util.Identifier;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import static eu.midnightdust.celestria.Celestria.MOD_ID;
public class ClientUtilsImpl {
public static void registerBuiltinResourcePack(Identifier id) {
FabricLoader.getInstance().getModContainer(MOD_ID).ifPresent(container -> {
ResourceManagerHelper.registerBuiltinResourcePack(id, container, ResourcePackActivationType.NORMAL);
});
}
public static void registerClientTick(boolean endTick, Consumer<MinecraftClient> code) {
if (endTick) ClientTickEvents.END_CLIENT_TICK.register(code::accept);
else ClientTickEvents.START_CLIENT_TICK.register(code::accept);
}
public static void registerDisconnectEvent(BiConsumer<ClientPlayNetworkHandler, MinecraftClient> code) {
ClientPlayConnectionEvents.DISCONNECT.register(code::accept);
}
}

View File

@@ -0,0 +1,13 @@
package eu.midnightdust.celestria.util.fabric;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.minecraft.world.World;
import java.util.function.Consumer;
public class CommonUtilsImpl {
public static void registerWorldTickEvent(boolean endTick, Consumer<World> code) {
if (endTick) ServerTickEvents.END_WORLD_TICK.register(code::accept);
else ServerTickEvents.START_WORLD_TICK.register(code::accept);
}
}

View File

@@ -0,0 +1,42 @@
package eu.midnightdust.celestria.util.fabric;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.server.network.ServerPlayerEntity;
import java.util.function.BiConsumer;
public class PacketUtilsImpl {
// Common
public static <T extends CustomPayload> void registerPayloadCommon(CustomPayload.Id<T> id, PacketCodec<RegistryByteBuf, T> codec) {
PayloadTypeRegistry.playC2S().register(id, codec);
PayloadTypeRegistry.playS2C().register(id, codec);
}
// Server
public static <T extends CustomPayload> void registerPayloadS2C(CustomPayload.Id<T> id, PacketCodec<RegistryByteBuf, T> codec) {
PayloadTypeRegistry.playS2C().register(id, codec);
}
public static void sendPlayPayloadS2C(ServerPlayerEntity player, CustomPayload payload) {
ServerPlayNetworking.send(player, payload);
}
public static void registerServerGlobalReceiver(CustomPayload.Id<?> type, BiConsumer<CustomPayload, PlayerEntity> code) {
ServerPlayNetworking.registerGlobalReceiver(type, (payload, context) -> code.accept(payload, context.player()));
}
// Client
public static <T extends CustomPayload> void registerPayloadC2S(CustomPayload.Id<T> id, PacketCodec<RegistryByteBuf, T> codec) {
PayloadTypeRegistry.playC2S().register(id, codec);
}
public static void sendPlayPayloadC2S(CustomPayload payload) {
ClientPlayNetworking.send(payload);
}
public static void registerClientGlobalReceiver(CustomPayload.Id<?> type, BiConsumer<CustomPayload, PlayerEntity> code) {
ClientPlayNetworking.registerGlobalReceiver(type, (payload, context) -> code.accept(payload, context.player()));
}
}

View File

@@ -0,0 +1,25 @@
package eu.midnightdust.celestria.util.fabric;
import eu.midnightdust.celestria.Celestria;
import eu.midnightdust.celestria.effect.InsomniaStatusEffect;
import eu.midnightdust.lib.util.MidnightColorUtil;
import eu.pb4.polymer.core.api.other.PolymerStatusEffect;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectCategory;
import net.minecraft.server.network.ServerPlayerEntity;
import org.jetbrains.annotations.Nullable;
public class PolymerUtilsImpl {
public static StatusEffect initInsomnia() {
return new PolymerInsomniaStatusEffect(StatusEffectCategory.HARMFUL, MidnightColorUtil.hex2Rgb("88A9C8").getRGB());
}
private static class PolymerInsomniaStatusEffect extends InsomniaStatusEffect implements PolymerStatusEffect {
public PolymerInsomniaStatusEffect(StatusEffectCategory statusEffectCategory, int color) {
super(statusEffectCategory, color);
}
public @Nullable StatusEffect getPolymerReplacement(ServerPlayerEntity player) {
if (Celestria.playersWithMod.contains(player.getUuid())) return this;
else return null;
}
}
}

View File

@@ -21,10 +21,10 @@
"environment": "*",
"entrypoints": {
"main": [
"eu.midnightdust.celestria.Celestria"
"eu.midnightdust.celestria.fabric.CelestriaFabric"
],
"client": [
"eu.midnightdust.celestria.CelestriaClient"
"eu.midnightdust.celestria.fabric.CelestriaFabric"
]
},

View File

@@ -1,18 +1,28 @@
# Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx1G
# Makes things faster
org.gradle.parallel=true
org.gradle.jvmargs=-Xmx2048M
# Fabric Properties
# check these on https://fabricmc.net/use
minecraft_version=1.19.2
yarn_mappings=1.19.2+build.4
loader_version=0.14.9
minecraft_version=1.21
supported_versions=1.21.1
yarn_mappings=1.21+build.2
enabled_platforms=fabric,neoforge
# Mod Properties
mod_version = 1.1.1
maven_group = eu.midnightdust
archives_base_name = celestria
archives_base_name=celestria
mod_version=2.0.0
maven_group=eu.midnightdust
release_type=release
curseforge_id=1085811
modrinth_id=GoCfVRkX
# Configure the IDs here after creating the projects on the websites
# Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
fabric_version=0.59.0+1.19.2
midnightlib_version=0.5.2
midnightlib_version=1.5.8
fabric_loader_version=0.15.11
fabric_api_version=0.100.1+1.21
polymer_version=0.9.6+1.21
neoforge_version=21.0.143
yarn_mappings_patch_neoforge_version = 1.21+build.4
quilt_loader_version=0.19.0-beta.18
quilt_fabric_api_version=7.0.1+0.83.0-1.20

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

112
neoforge/build.gradle Normal file
View File

@@ -0,0 +1,112 @@
plugins {
id 'com.github.johnrengelman.shadow'
id "me.shedaniel.unified-publishing"
}
repositories {
maven {
name = 'NeoForged'
url = 'https://maven.neoforged.net/releases'
}
}
architectury {
platformSetupLoomIde()
neoForge()
}
loom {
accessWidenerPath = project(":common").loom.accessWidenerPath
}
configurations {
common {
canBeResolved = true
canBeConsumed = false
}
compileClasspath.extendsFrom common
runtimeClasspath.extendsFrom common
developmentNeoForge.extendsFrom common
// Files in this configuration will be bundled into your mod using the Shadow plugin.
// Don't use the `shadow` configuration from the plugin itself as it's meant for excluding files.
shadowBundle {
canBeResolved = true
canBeConsumed = false
}
archivesBaseName = rootProject.archives_base_name + "-neoforge"
}
dependencies {
neoForge "net.neoforged:neoforge:$rootProject.neoforge_version"
modImplementation include ("maven.modrinth:midnightlib:${rootProject.midnightlib_version}-neoforge")
common(project(path: ':common', configuration: 'namedElements')) { transitive false }
shadowBundle project(path: ':common', configuration: 'transformProductionNeoForge')
}
processResources {
inputs.property 'version', project.version
filesMatching('META-INF/neoforge.mods.toml') {
expand version: project.version
}
}
shadowJar {
configurations = [project.configurations.shadowBundle]
archiveClassifier = 'dev-shadow'
}
remapJar {
input.set shadowJar.archiveFile
}
sourcesJar {
def commonSources = project(":common").sourcesJar
dependsOn commonSources
from commonSources.archiveFile.map { zipTree(it) }
}
components.java {
withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
skip()
}
}
unifiedPublishing {
project {
displayName = "Celestria $project.version - NeoForge $project.minecraft_version"
releaseType = "$project.release_type"
changelog = releaseChangelog()
gameVersions = []
gameLoaders = ["neoforge"]
mainPublication remapJar
relations {
includes {
curseforge = "midnightlib"
modrinth = "midnightlib"
}
}
var CURSEFORGE_TOKEN = project.findProperty("CURSEFORGE_TOKEN") ?: System.getenv("CURSEFORGE_TOKEN")
if (CURSEFORGE_TOKEN != null) {
curseforge {
token = CURSEFORGE_TOKEN
id = rootProject.curseforge_id
gameVersions.addAll "Java 21", project.minecraft_version, project.supported_versions
}
}
var MODRINTH_TOKEN = project.findProperty("MODRINTH_TOKEN") ?: System.getenv("MODRINTH_TOKEN")
if (MODRINTH_TOKEN != null) {
modrinth {
token = MODRINTH_TOKEN
id = rootProject.modrinth_id
version = "$project.version-$project.name"
gameVersions.addAll project.minecraft_version, project.supported_versions
}
}
}
}

View File

@@ -0,0 +1 @@
loom.platform=neoforge

View File

@@ -0,0 +1,43 @@
package eu.midnightdust.celestria.neoforge;
import eu.midnightdust.celestria.Celestria;
import eu.midnightdust.celestria.CelestriaClient;
import eu.midnightdust.celestria.effect.StatusEffectInit;
import net.minecraft.registry.BuiltinRegistries;
import net.minecraft.registry.Registries;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.registries.NeoForgeRegistries;
import net.neoforged.neoforge.registries.RegisterEvent;
import static eu.midnightdust.celestria.Celestria.MOD_ID;
import static eu.midnightdust.celestria.Celestria.id;
@Mod(value = MOD_ID)
public class CelestriaNeoForge {
public CelestriaNeoForge() {
Celestria.init();
}
@Mod(value = MOD_ID, dist = Dist.CLIENT)
public static class CelestriaClientNeoforge {
public CelestriaClientNeoforge() {
CelestriaClient.init();
}
}
@EventBusSubscriber(modid = MOD_ID, bus = EventBusSubscriber.Bus.MOD)
public class GameEvents {
@SubscribeEvent
public static void register(RegisterEvent event) {
event.register(
Registries.STATUS_EFFECT.getKey(),
registry -> {
registry.register(id("insomnia"), StatusEffectInit.INSOMNIA);
StatusEffectInit.INSOMNIA_EFFECT = Registries.STATUS_EFFECT.getEntry(StatusEffectInit.INSOMNIA);
}
);
}
}
}

View File

@@ -0,0 +1,88 @@
package eu.midnightdust.celestria.util.neoforge;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.resource.DirectoryResourcePack;
import net.minecraft.resource.ResourcePackInfo;
import net.minecraft.resource.ResourcePackPosition;
import net.minecraft.resource.ResourcePackProfile;
import net.minecraft.resource.ResourcePackSource;
import net.minecraft.resource.ResourceType;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.ModList;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.client.event.ClientPlayerNetworkEvent;
import net.neoforged.neoforge.client.event.ClientTickEvent;
import net.neoforged.neoforge.event.AddPackFindersEvent;
import net.neoforged.neoforgespi.locating.IModFile;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import static eu.midnightdust.celestria.Celestria.MOD_ID;
public class ClientUtilsImpl {
public final static MinecraftClient client = MinecraftClient.getInstance();
static List<Identifier> packsToRegister = new ArrayList<>();
static List<BiConsumer<ClientPlayNetworkHandler, MinecraftClient>> disconnectHandlers = new ArrayList<>();
static Set<Consumer<MinecraftClient>> endClientTickEvents = new HashSet<>();
static Set<Consumer<MinecraftClient>> startClientTickEvents = new HashSet<>();
public static void registerBuiltinResourcePack(Identifier id) {
packsToRegister.add(id);
}
public static void registerClientTick(boolean endTick, Consumer<MinecraftClient> code) {
if (endTick) endClientTickEvents.add(code);
else startClientTickEvents.add(code);
}
public static void registerDisconnectEvent(BiConsumer<ClientPlayNetworkHandler, MinecraftClient> code) {
disconnectHandlers.add(code);
}
@EventBusSubscriber(modid = MOD_ID, bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
public class ClientEvents {
@SubscribeEvent
public static void addPackFinders(AddPackFindersEvent event) {
if (event.getPackType() == ResourceType.CLIENT_RESOURCES) {
packsToRegister.forEach(id -> registerResourcePack(event, id, false));
packsToRegister.clear();
}
}
private static void registerResourcePack(AddPackFindersEvent event, Identifier id, boolean alwaysEnabled) {
event.addRepositorySource(((profileAdder) -> {
IModFile file = ModList.get().getModFileById(id.getNamespace()).getFile();
try {
ResourcePackProfile.PackFactory pack = new DirectoryResourcePack.DirectoryBackedFactory(file.findResource("resourcepacks/" + id.getPath()));
ResourcePackInfo info = new ResourcePackInfo(id.toString(), Text.of(id.getNamespace()+"/"+id.getPath()), ResourcePackSource.BUILTIN, Optional.empty());
ResourcePackProfile packProfile = ResourcePackProfile.create(info, pack, ResourceType.CLIENT_RESOURCES, new ResourcePackPosition(alwaysEnabled, ResourcePackProfile.InsertionPosition.TOP, false));
if (packProfile != null) {
profileAdder.accept(packProfile);
}
} catch (NullPointerException e) {e.fillInStackTrace();}
}));
}
}
@EventBusSubscriber(modid = MOD_ID, bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT)
public class ClientGameEvents {
@SubscribeEvent
public static void onDisconnect(ClientPlayerNetworkEvent.LoggingOut event) {
if (event.getPlayer() != null) disconnectHandlers.forEach(handler -> handler.accept(event.getPlayer().networkHandler, client));
}
@SubscribeEvent
public static void startClientTick(ClientTickEvent.Pre event) {
startClientTickEvents.forEach(code -> code.accept(client));
}
@SubscribeEvent
public static void endClientTick(ClientTickEvent.Pre event) {
endClientTickEvents.forEach(code -> code.accept(client));
}
}
}

View File

@@ -0,0 +1,34 @@
package eu.midnightdust.celestria.util.neoforge;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.world.World;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.event.tick.LevelTickEvent;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;
import static eu.midnightdust.celestria.Celestria.MOD_ID;
public class CommonUtilsImpl {
static Set<Consumer<World>> startWorldTickEvents = new HashSet<>();
static Set<Consumer<World>> endWorldTickEvents = new HashSet<>();
public static void registerWorldTickEvent(boolean endTick, Consumer<World> code) {
if (endTick) endWorldTickEvents.add(code);
else startWorldTickEvents.add(code);
}
@EventBusSubscriber(modid = MOD_ID, bus = EventBusSubscriber.Bus.GAME)
public class GameEvents {
@SubscribeEvent
public static void startWorldTick(LevelTickEvent.Pre event) {
startWorldTickEvents.forEach(code -> code.accept(event.getLevel()));
}
@SubscribeEvent
public static void endWorldTick(LevelTickEvent.Pre event) {
endWorldTickEvents.forEach(code -> code.accept(event.getLevel()));
}
}
}

View File

@@ -0,0 +1,76 @@
package eu.midnightdust.celestria.util.neoforge;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.NetworkSide;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.server.network.ServerPlayerEntity;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
import net.neoforged.neoforge.network.registration.PayloadRegistrar;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import static eu.midnightdust.celestria.Celestria.MOD_ID;
public class PacketUtilsImpl {
static Map<CustomPayload.Id, PayloadStorage> payloads = new HashMap<>();
private record PayloadStorage <T extends CustomPayload> (boolean client, boolean server, PacketCodec<RegistryByteBuf, T> codec, BiConsumer<CustomPayload, PlayerEntity> clientReceiver, BiConsumer<CustomPayload, PlayerEntity> serverReceiver) {}
// Common
public static <T extends CustomPayload> void registerPayloadCommon(CustomPayload.Id<T> id, PacketCodec<RegistryByteBuf, T> codec) {
payloads.put(id, new PayloadStorage<>(true, true, codec, (p, e) -> {}, (p, e) -> {}));
}
// Server
public static <T extends CustomPayload> void registerPayloadS2C(CustomPayload.Id<T> id, PacketCodec<RegistryByteBuf, T> codec) {
payloads.put(id, new PayloadStorage<>(false, true, codec, (p, e) -> {}, (p, e) -> {}));
}
public static void sendPlayPayloadS2C(ServerPlayerEntity player, CustomPayload payload) {
player.networkHandler.send(payload);
}
public static void registerServerGlobalReceiver(CustomPayload.Id<?> type, BiConsumer<CustomPayload, PlayerEntity> code) {
payloads.compute(type, (k, data) -> new PayloadStorage<>(data.client, data.server, data.codec, data.clientReceiver, code));
}
// Client
public static <T extends CustomPayload> void registerPayloadC2S(CustomPayload.Id<T> id, PacketCodec<RegistryByteBuf, T> codec) {
payloads.put(id, new PayloadStorage<>(true, false, codec, (p, e) -> {}, (p, e) -> {}));
}
public static void sendPlayPayloadC2S(CustomPayload payload) {
if (PlatformFunctions.isClientEnv() && ClientUtilsImpl.client.getNetworkHandler() != null) ClientUtilsImpl.client.getNetworkHandler().send(payload);
}
public static void registerClientGlobalReceiver(CustomPayload.Id<?> type, BiConsumer<CustomPayload, PlayerEntity> code) {
payloads.compute(type, (k, data) -> new PayloadStorage<>(data.client, data.server, data.codec, code, data.serverReceiver));
}
@EventBusSubscriber(modid = MOD_ID, bus = EventBusSubscriber.Bus.MOD)
public class CommonEvents {
@SubscribeEvent
public static void registerPayloads(RegisterPayloadHandlersEvent event) {
PayloadRegistrar registrar = event.registrar("1");
payloads.forEach((id, payload) -> {
if (payload.client && payload.server) {
registrar.playBidirectional(id, payload.codec, (data, context) -> {
if (context.flow() == NetworkSide.CLIENTBOUND) payload.clientReceiver.accept(data, context.player());
else payload.serverReceiver.accept(data, context.player());
});
}
else if (payload.client) {
registrar.playToServer(id, payload.codec, (data, context) -> {
payload.clientReceiver.accept(data, context.player());
});
}
else {
registrar.playToClient(id, payload.codec, (data, context) -> {
payload.clientReceiver.accept(data, context.player());
});
}
});
}
}
}

View File

@@ -0,0 +1,9 @@
package eu.midnightdust.celestria.util.neoforge;
import net.minecraft.entity.effect.StatusEffect;
public class PolymerUtilsImpl {
public static StatusEffect initInsomnia() {
return null;
}
}

View File

@@ -0,0 +1,38 @@
modLoader = "javafml"
loaderVersion = "[2,)"
#issueTrackerURL = ""
license = "MIT License"
[[mods]]
modId = "celestria"
version = "${version}"
displayName = "Celestria"
logoFile = "icon.png"
authors = "Motschen"
description = '''
Adds celestrial events, such as shooting stars and occasional insomnia from full moon.
'''
[[mixins]]
config = "celestria.mixins.json"
[[dependencies.celestria]]
modId = "neoforge"
mandatory = true
versionRange = "[21.0,)"
ordering = "NONE"
side = "BOTH"
[[dependencies.celestria]]
modId = "minecraft"
mandatory = true
versionRange = "[1.21,)"
ordering = "NONE"
side = "BOTH"
[[dependencies.celestria]]
modId = "midnightlib"
mandatory = true
versionRange = "[1.0,)"
ordering = "AFTER"
side = "BOTH"

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -1,10 +1,15 @@
pluginManagement {
repositories {
jcenter()
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
maven { url "https://maven.fabricmc.net/" }
maven { url "https://maven.architectury.dev/" }
maven { url "https://maven.neoforged.net/releases" }
gradlePluginPortal()
}
}
include("common")
include("fabric")
//include("quilt") // Native quilt support is disabled atm, as the Quilt libraries are currently in maintenance mode
include("neoforge")
rootProject.name = "celestria"

View File

@@ -1,88 +0,0 @@
package eu.midnightdust.celestria;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import eu.midnightdust.lib.util.MidnightColorUtil;
import eu.midnightdust.celestria.config.CelestriaConfig;
import eu.midnightdust.celestria.effect.InsomniaStatusEffect;
import io.netty.buffer.Unpooled;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.command.argument.EntityArgumentType;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectCategory;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.random.Random;
import net.minecraft.util.registry.Registry;
import java.util.Collection;
public class Celestria implements ModInitializer {
public static final String MOD_ID = "celestria";
public static final Random random = Random.create();
public static final Identifier SHOOTING_STAR_PACKET = new Identifier(MOD_ID, "shooting_star");
public static final Identifier WELCOME_PACKET = new Identifier(MOD_ID, "welcome");
public static final StatusEffect INSOMNIA = new InsomniaStatusEffect(StatusEffectCategory.HARMFUL, MidnightColorUtil.hex2Rgb("88A9C8").getRGB());
public static int shootingStarCooldown = 0;
private int prevPlayerAmount = 0;
public void onInitialize() {
CelestriaConfig.init(MOD_ID, CelestriaConfig.class);
Registry.register(Registry.STATUS_EFFECT, new Identifier(MOD_ID, "insomnia"), INSOMNIA);
LiteralArgumentBuilder<ServerCommandSource> command = CommandManager.literal("shootingStar").then(CommandManager.argument("players", EntityArgumentType.players())
.requires(source -> source.hasPermissionLevel(2)).executes(ctx -> createShootingStar(EntityArgumentType.getPlayers(ctx, "players"), random.nextBetween(100, 150), random.nextInt(360), random.nextInt(3)))
.then(CommandManager.argument("x", IntegerArgumentType.integer(90, 180))
.requires(source -> source.hasPermissionLevel(2)).then(CommandManager.argument("y", IntegerArgumentType.integer(0, 360))
.then(CommandManager.argument("type", IntegerArgumentType.integer(0, 3)).requires(source -> source.hasPermissionLevel(2)).executes(ctx -> createShootingStar(EntityArgumentType.getPlayers(ctx, "players"),
IntegerArgumentType.getInteger(ctx, "x"), IntegerArgumentType.getInteger(ctx, "y"), IntegerArgumentType.getInteger(ctx, "type")))))));
LiteralArgumentBuilder<ServerCommandSource> finalized = CommandManager.literal("celestria").then(command).requires(source -> source.hasPermissionLevel(2));
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated, registrationEnvironment) -> dispatcher.register(finalized));
ServerTickEvents.END_WORLD_TICK.register(world -> {
if (shootingStarCooldown > 0) --shootingStarCooldown;
if (world.getPlayers().size() > prevPlayerAmount && CelestriaConfig.enableShootingStars) {
world.getPlayers().forEach(player -> ServerPlayNetworking.send(player, WELCOME_PACKET, new PacketByteBuf(Unpooled.buffer())));
prevPlayerAmount = world.getPlayers().size();
}
if (world.isNight() && CelestriaConfig.enableInsomnia && world.getMoonPhase() == 0) {
for (ServerPlayerEntity player : world.getPlayers()) {
if (world.random.nextInt(CelestriaConfig.insomniaChance) == 0) {
player.addStatusEffect(new StatusEffectInstance(INSOMNIA, CelestriaConfig.insomniaDuration, 0, true, false, true));
}
}
}
if (world.isNight() && CelestriaConfig.enableShootingStars && Celestria.shootingStarCooldown <= 0 && world.random.nextInt(CelestriaConfig.shootingStarChance) == 0) {
int x = world.random.nextBetween(100, 150);
int y = world.random.nextInt(360);
int type = world.random.nextInt(3);
createShootingStar(world.getPlayers(), x, y, type);
Celestria.shootingStarCooldown = CelestriaConfig.shootingStarCooldownLength;
}
});
}
public int createShootingStar(Collection<ServerPlayerEntity> players, int x, int y, int type) {
int[] array = new int[3];
array[0] = x;
array[1] = y;
array[2] = type;
PacketByteBuf passedData = new PacketByteBuf(Unpooled.buffer());
passedData.writeIntArray(array);
int message = Random.create().nextInt(CelestriaConfig.shootingStarMessages.size());
players.forEach(player -> {
player.addStatusEffect(new StatusEffectInstance(StatusEffects.LUCK, CelestriaConfig.shootingStarLuckDuration, 0, true, false, true));
ServerPlayNetworking.send(player, SHOOTING_STAR_PACKET, passedData);
if (CelestriaConfig.sendChatMessages) player.sendMessageToClient(Text.literal("§f§l[§7§lC§8§le§7§ll§f§le§7§ls§8§lt§7§lr§f§li§7§la§8§l] ").append(Text.translatable(CelestriaConfig.shootingStarMessages.get(message))),false);
});
return 1;
}
}

View File

@@ -1,58 +0,0 @@
package eu.midnightdust.celestria;
import eu.midnightdust.celestria.config.CelestriaConfig;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.util.Identifier;
public class CelestriaClient implements ClientModInitializer {
private static boolean clientOnlyMode = true;
public static int shootingStarProgress = 0;
public static int shootingStarType = 0;
public static int shootingStarX = 0;
public static int shootingStarY = 0;
@Override
public void onInitializeClient() {
FabricLoader.getInstance().getModContainer(Celestria.MOD_ID).ifPresent(modContainer -> {
ResourceManagerHelper.registerBuiltinResourcePack(new Identifier(Celestria.MOD_ID,"realistic"), modContainer, ResourcePackActivationType.NORMAL);
ResourceManagerHelper.registerBuiltinResourcePack(new Identifier(Celestria.MOD_ID,"pixelperfect"), modContainer, ResourcePackActivationType.NORMAL);
});
ClientPlayNetworking.registerGlobalReceiver(Celestria.SHOOTING_STAR_PACKET,
(client, handler, attachedData, packetSender) -> {
int[] array = attachedData.readIntArray(3);
client.execute(() -> {
if (client.world != null) {
CelestriaClient.clientOnlyMode = false; // If the welcome packet wasn't received correctly for some reason, disable clientOnlyMode on shooting star occurrence
CelestriaClient.shootingStarX = array[0];
CelestriaClient.shootingStarY = array[1];
CelestriaClient.shootingStarType = array[2];
CelestriaClient.shootingStarProgress = CelestriaConfig.shootingStarPathLength + shootingStarType * 10;
}
});
});
ClientPlayNetworking.registerGlobalReceiver(Celestria.WELCOME_PACKET,
(client, handler, attachedData, packetSender) -> client.execute(() -> CelestriaClient.clientOnlyMode = false));
ClientTickEvents.END_CLIENT_TICK.register(client -> {
if (shootingStarProgress > 0) --shootingStarProgress;
if (CelestriaClient.clientOnlyMode && CelestriaConfig.enableShootingStars && client.world != null) {
if (Celestria.shootingStarCooldown > 0) {
--Celestria.shootingStarCooldown;
}
if (Celestria.shootingStarCooldown <= 0 && (180 < client.world.getSkyAngle(client.getTickDelta()) * 360 && 270 > client.world.getSkyAngle(client.getTickDelta()) * 360) && Celestria.random.nextInt(CelestriaConfig.shootingStarChance) == 0) {
CelestriaClient.shootingStarX = Celestria.random.nextBetween(100, 150);
CelestriaClient.shootingStarY = Celestria.random.nextInt(360);
CelestriaClient.shootingStarType = Celestria.random.nextInt(3);
CelestriaClient.shootingStarProgress = CelestriaConfig.shootingStarPathLength + CelestriaClient.shootingStarType * 10;
Celestria.shootingStarCooldown = CelestriaConfig.shootingStarCooldownLength;
}
}
});
ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> CelestriaClient.clientOnlyMode = true);
}
}

View File

@@ -1,22 +0,0 @@
package eu.midnightdust.celestria.config;
import com.google.common.collect.Lists;
import eu.midnightdust.lib.config.MidnightConfig;
import java.util.List;
public class CelestriaConfig extends MidnightConfig {
@Entry public static boolean sendChatMessages = true;
@Entry public static boolean enableShootingStars = true;
@Entry public static float shootingStarScale = 1.5f;
@Entry public static float shootingStarSpeed = 0.5f;
@Entry public static int shootingStarPathLength = 100;
@Entry public static int shootingStarChance = 20000;
@Entry public static int shootingStarCooldownLength = 1000;
@Entry public static int shootingStarLuckDuration = 1000;
@Entry public static List<String> shootingStarMessages = Lists.newArrayList("celestria.shootingStar.1", "celestria.shootingStar.2", "celestria.shootingStar.3");
@Entry public static boolean enableInsomnia = true;
@Entry public static int insomniaChance = 30000;
@Entry public static int insomniaDuration = 1000;
@Entry public static List<String> insomniaMessages = Lists.newArrayList("celestria.insomnia.1", "celestria.insomnia.2");
}

View File

@@ -1,25 +0,0 @@
package eu.midnightdust.celestria.mixin;
import eu.midnightdust.celestria.render.ShootingStarRenderer;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.util.math.Matrix4f;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(WorldRenderer.class)
public abstract class MixinWorldRenderer {
@Unique private final ShootingStarRenderer shootingStarRenderer = new ShootingStarRenderer();
@Shadow @Nullable private ClientWorld world;
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/util/profiler/Profiler;swap(Ljava/lang/String;)V", ordinal = 6, shift = At.Shift.BEFORE), method = "render")
public void celestria$renderShootingStars(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix, CallbackInfo ci) {
shootingStarRenderer.renderShootingStar(world, matrices);
}
}

View File

@@ -1,46 +0,0 @@
package eu.midnightdust.celestria.render;
import com.mojang.blaze3d.systems.RenderSystem;
import eu.midnightdust.celestria.Celestria;
import eu.midnightdust.celestria.CelestriaClient;
import eu.midnightdust.celestria.config.CelestriaConfig;
import eu.midnightdust.lib.util.MidnightMathUtil;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Matrix4f;
import net.minecraft.util.math.Vec3f;
public class ShootingStarRenderer {
public void renderShootingStar(ClientWorld world, MatrixStack matrices) {
if (world != null && CelestriaConfig.enableShootingStars && CelestriaClient.shootingStarProgress > 0) {
world.getProfiler().swap("shooting_star");
matrices.push();
matrices.scale(CelestriaConfig.shootingStarScale,CelestriaConfig.shootingStarScale,CelestriaConfig.shootingStarScale);
matrices.multiply(Vec3f.POSITIVE_Y.getDegreesQuaternion(MidnightMathUtil.isEven(CelestriaClient.shootingStarType) ? CelestriaClient.shootingStarY + CelestriaClient.shootingStarProgress*CelestriaConfig.shootingStarSpeed : CelestriaClient.shootingStarY - CelestriaClient.shootingStarProgress*CelestriaConfig.shootingStarSpeed));
matrices.multiply(Vec3f.POSITIVE_X.getDegreesQuaternion(CelestriaClient.shootingStarX+(CelestriaClient.shootingStarProgress*CelestriaConfig.shootingStarSpeed*0.05f)));
Matrix4f matrix4f = matrices.peek().getPositionMatrix();
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer();
RenderSystem.enableTexture();
RenderSystem.defaultBlendFunc();
RenderSystem.enableDepthTest();
RenderSystem.enableBlend();
float alpha = (float) (Math.log(CelestriaClient.shootingStarProgress) / 5f);
RenderSystem.setShaderColor(1,1,1,alpha);
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, new Identifier(Celestria.MOD_ID, "textures/environment/shooting_star"+(CelestriaClient.shootingStarType+1)+".png"));
bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE);
bufferBuilder.vertex(matrix4f, -20.0F, -100.0F, 20.0F).texture(0.0F, 0.0F).next();
bufferBuilder.vertex(matrix4f, 20.0F, -100.0F, 20.0F).texture(1.0F, 0.0F).next();
bufferBuilder.vertex(matrix4f, 20.0F, -100.0F, -20.0F).texture(1.0F, 1.0F).next();
bufferBuilder.vertex(matrix4f, -20.0F, -100.0F, -20.0F).texture(0.0F, 1.0F).next();
BufferRenderer.drawWithShader(bufferBuilder.end());
RenderSystem.disableTexture();
matrices.pop();
}
}
}

View File

@@ -1,22 +0,0 @@
{
"celestria.midnightconfig.title": "Celestria Config",
"celestria.midnightconfig.sendChatMessages": "Send Chat Messages on Events",
"celestria.midnightconfig.enableShootingStars": "Enable Shooting Stars",
"celestria.midnightconfig.shootingStarScale": "Shooting Star Scale",
"celestria.midnightconfig.shootingStarSpeed": "Shooting Star Speed",
"celestria.midnightconfig.shootingStarPathLength": "Shooting Star Path Length",
"celestria.midnightconfig.shootingStarChance": "Shooting Star Chance",
"celestria.midnightconfig.shootingStarCooldownLength": "Shooting Star Cooldown Length",
"celestria.midnightconfig.shootingStarLuckDuration": "Shooting Star Luck Duration",
"celestria.midnightconfig.shootingStarMessages": "Shooting Star Messages",
"celestria.midnightconfig.enableInsomnia": "Enable Insomnia",
"celestria.midnightconfig.insomniaChance": "Insomnia Chance",
"celestria.midnightconfig.insomniaMessages": "Insomnia Messages",
"celestria.midnightconfig.insomniaDuration": "Insomnia Effect Duration",
"celestria.shootingStar.1": "§eOh, look! A shooting star appeared and blessed you with good luck!",
"celestria.shootingStar.2": "§6Wow, a shooting star appeared, make a wish!",
"celestria.shootingStar.3": "§2♪ Can we pretend that airplanes in the night sky are like shooting stars... ♫\n§3Oh wait, there's a real one!",
"celestria.insomnia.1": "§cYou're afraid of the full moon, so you just can't find no rest...",
"celestria.insomnia.2": "§3Ouuwwwh... You hear strange noises from afar and can't close your eyes",
"effect.celestria.insomnia": "Insomnia"
}