Compare commits

..

2 commits

Author SHA1 Message Date
fac39623de
Bump version, fix translation and add icon 2024-11-01 14:32:10 +01:00
bd5f380091
Add alternative ending 2024-11-01 13:55:07 +01:00
7 changed files with 110 additions and 4 deletions

View file

@ -3,6 +3,8 @@
This Minecraft mod allows you to prevent the world generator from generating new chunks past a defined limit.
You can set the limit by changing the gamerule `chunkGenerationLimit`.
This mod also adds an alternative ending. You can turn this off with `/gamerule truncatedAlternativeEnding false`.
Requires Fabric API!
## Known Incompatibilities

View file

@ -9,7 +9,7 @@ yarn_mappings=1.21.1+build.3
loader_version=0.16.7
# Mod Properties
mod_version=0.1.0
mod_version=0.2.0
maven_group=net.chaoticbyte.truncated
archives_base_name=truncated

View file

@ -0,0 +1,35 @@
package net.chaoticbyte.truncated;
import com.mojang.serialization.Codec;
import net.minecraft.advancement.criterion.AbstractCriterion;
import net.minecraft.predicate.entity.LootContextPredicate;
import net.minecraft.predicate.entity.LootContextPredicateValidator;
import net.minecraft.server.network.ServerPlayerEntity;
import java.util.Optional;
public class PlayerReachedLimitCriterion extends AbstractCriterion<PlayerReachedLimitCriterion.Conditions> {
public void trigger(ServerPlayerEntity player) {
this.trigger(player, conditions -> true);
}
// practically unnecessary boilerplate:
@Override
public Codec<Conditions> getConditionsCodec() {
return PlayerReachedLimitCriterion.Conditions.CODEC;
}
public record Conditions() implements AbstractCriterion.Conditions {
public static final Codec<PlayerReachedLimitCriterion.Conditions> CODEC = Codec.unit(new PlayerReachedLimitCriterion.Conditions());
@Override
public void validate(LootContextPredicateValidator validator) {}
@Override
public Optional<LootContextPredicate> player() {
return Optional.empty();
}
}
}

View file

@ -3,21 +3,43 @@ package net.chaoticbyte.truncated;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.gamerule.v1.GameRuleFactory;
import net.fabricmc.fabric.api.gamerule.v1.GameRuleRegistry;
import net.minecraft.advancement.criterion.Criteria;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.GameRules;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
public class Truncated implements ModInitializer {
public static final String MOD_ID = "truncated";
public static final GameRules.Key<GameRules.IntRule> CHUNK_GEN_LIMIT_KEY = GameRuleRegistry.register(
"chunkGenerationLimit", GameRules.Category.MISC, GameRuleFactory.createIntRule((28_000_000 / 16) - 1 ));
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
// gamerules
public static final GameRules.Key<GameRules.IntRule> CHUNK_GEN_LIMIT_KEY = GameRuleRegistry.register(
"chunkGenerationLimit",
GameRules.Category.MISC,
GameRuleFactory.createIntRule((28_000_000 / 16) - 1 )
);
public static final GameRules.Key<GameRules.BooleanRule> TRUNCATED_ALT_ENDING = GameRuleRegistry.register(
"truncatedAlternativeEnding",
GameRules.Category.MISC,
GameRuleFactory.createBooleanRule (true)
);
// advancement criterion
public static PlayerReachedLimitCriterion PLAYER_REACHED_LIMIT = Criteria.register(
MOD_ID + "/reached_limit",
new PlayerReachedLimitCriterion());
// variable temporary holding the server reference later
private static MinecraftServer server;
// get the limit set by the gamerule
public static int getLimit() {
return server.getGameRules().getInt(CHUNK_GEN_LIMIT_KEY);
}
@ -27,6 +49,30 @@ public class Truncated implements ModInitializer {
ServerLifecycleEvents.SERVER_STARTING.register(minecraftServer -> {
server = minecraftServer;
});
ServerTickEvents.START_WORLD_TICK.register(minecraftServer -> {
if (minecraftServer.getGameRules().getBoolean(TRUNCATED_ALT_ENDING)) {
float currentBlockLimit = getLimit() * 16;
java.util.List<net.minecraft.server.network.ServerPlayerEntity> playerEntitiesReachedEnd = new ArrayList<>();
minecraftServer.getPlayers().forEach(playerEntity -> {
if (!playerEntity.isSpectator()) {
Vec3d playerPos = playerEntity.getPos();
if (
playerPos.x > currentBlockLimit + 16
|| playerPos.x < -currentBlockLimit
|| playerPos.z > currentBlockLimit + 16
|| playerPos.z < -currentBlockLimit
) {
playerEntitiesReachedEnd.add(playerEntity);
}
}
});
// trigger the end credits for all players out of bounds
playerEntitiesReachedEnd.forEach(playerEntity -> {
PLAYER_REACHED_LIMIT.trigger(playerEntity); // trigger advancement
playerEntity.detachForDimensionChange(); // end credits
});
}
});
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Before After
Before After

View file

@ -1,3 +1,4 @@
{
"gamerule.chunkGenerationLimit": "Chunk Generation Limit"
"gamerule.chunkGenerationLimit": "(Truncated) Chunk Generation Limit",
"gamerule.truncatedAlternativeEnding": "(Truncated) Enable Alternative World Ending"
}

View file

@ -0,0 +1,22 @@
{
"parent": "minecraft:story/root",
"criteria": {
"reached_limit": {"conditions": {}, "trigger": "minecraft:truncated/reached_limit"}
},
"display": {
"announce_to_chat": true,
"description": {
"text": "You have traveled beyond the natural limits of this world (alternative ending)"
},
"frame": "goal",
"hidden": false,
"icon": {
"id": "minecraft:compass"
},
"title": {
"text": "The Limits of this World"
},
"show_toast": true
},
"requirements": [["reached_limit"]]
}