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

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