add: random events

This commit is contained in:
iceBear67 committed 2024-07-10 00:43:02 +08:00
1 parent 2fbfc23ef6
commit 9066295d75
6 files changed
+125

No files matched your search

@@ -7,6 +7,8 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import io.ib67.sfcraft.config.SFConfig;
import io.ib67.sfcraft.geoip.GeoIPService;
import io.ib67.sfcraft.registry.event.RandomEventRegistry;
import io.ib67.sfcraft.registry.event.SFRandomEventRegistry;
import lombok.Getter;
import lombok.SneakyThrows;
import net.fabricmc.api.ModInitializer;
@@ -38,6 +40,8 @@ public class SFCraft implements ModInitializer {
private String motd;
@Getter
private String updateLog;
@Getter
private RandomEventRegistry randomEventRegistry;
@Override
@SneakyThrows
@@ -52,12 +56,17 @@ public class SFCraft implements ModInitializer {
motd = loadMotd();
updateLog = loadUpdateLog();
geoIPService = new GeoIPService();
this.setupRandomEvents();
ServerPlayConnectionEvents.JOIN.register(listener::onPlayerJoin);
CommandRegistrationCallback.EVENT.register(this::registerCommands);
ServerLifecycleEvents.SERVER_STARTED.register(this::onServerStarted);
}
private void setupRandomEvents() {
randomEventRegistry = new SFRandomEventRegistry();
}
private void onServerStarted(MinecraftServer minecraftServer) {
server = minecraftServer;
server.setMotd(motd);
@@ -0,0 +1,15 @@
package io.ib67.sfcraft.event;
import net.minecraft.registry.RegistryKey;
import net.minecraft.world.World;
public abstract class RandomEvent {
/**
* @return duration
*/
public abstract int start();
public abstract void onUpdate(int ticks);
public abstract void end();
}
@@ -0,0 +1,8 @@
package io.ib67.sfcraft.registry.event;
import io.ib67.sfcraft.event.RandomEvent;
public interface ActiveEvent {
RandomEvent getEvent();
int getRemainingTicks();
}
@@ -0,0 +1,13 @@
package io.ib67.sfcraft.registry.event;
import io.ib67.sfcraft.event.RandomEvent;
import net.minecraft.world.World;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
public interface RandomEventRegistry {
List<ActiveEvent> getActiveEvents();
void registerEvent(Function<World, RandomEvent> event, Predicate<World> worldTickPredicate);
}
@@ -0,0 +1,7 @@
package io.ib67.sfcraft.registry.event;
public class SFRandomEventRegistry extends SimpleRandomEventRegistry {
public SFRandomEventRegistry() {
}
}
@@ -0,0 +1,73 @@
package io.ib67.sfcraft.registry.event;
import io.ib67.sfcraft.event.RandomEvent;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
public class SimpleRandomEventRegistry implements RandomEventRegistry {
private final List<RegisteredEntry> entries = new ArrayList<>();
private final List<StartedEntry> activeEvents = new ArrayList<>();
protected SimpleRandomEventRegistry() {
ServerTickEvents.END_WORLD_TICK.register(this::afterWorldTick);
}
private void afterWorldTick(ServerWorld serverWorld) {
for (RegisteredEntry entry : entries) {
if (!entry.started && entry.worldTickPredicate.test(serverWorld)) {
var event = entry.event.apply(serverWorld);
activeEvents.add(new StartedEntry(event, () -> entry.started = false, event.start()));
}
}
var it = activeEvents.iterator();
while (it.hasNext()) {
var entry = it.next();
entry.event.onUpdate(++entry.ticks);
if (entry.ticks >= entry.maxTicks) {
it.remove();
entry.event.end();
entry.afterEvent.run();
}
}
}
@Override
@SuppressWarnings("unchecked")
public List<ActiveEvent> getActiveEvents() {
return (List<ActiveEvent>) (Object) activeEvents;
}
@Override
public void registerEvent(Function<World, RandomEvent> event, Predicate<World> worldTickPredicate) {
entries.add(new RegisteredEntry(event, worldTickPredicate));
}
@RequiredArgsConstructor
private static final class StartedEntry implements ActiveEvent {
@Getter
private final RandomEvent event;
private final Runnable afterEvent;
private final int maxTicks;
private int ticks;
@Override
public int getRemainingTicks() {
return maxTicks - ticks;
}
}
@RequiredArgsConstructor
private static final class RegisteredEntry {
private final Function<World, RandomEvent> event;
private final Predicate<World> worldTickPredicate;
private boolean started;
}
}