mew let mep spawn
This commit is contained in:
parent
9b44fcf4e0
commit
8cfc27cb70
@ -1,135 +1,42 @@
|
||||
package net.Chipperfluff.chipi;
|
||||
|
||||
import net.Chipperfluff.chipi.advancement.ModCriteria;
|
||||
import net.Chipperfluff.chipi.block.ChipperPortalBlock;
|
||||
import net.Chipperfluff.chipi.block.ModBlocks;
|
||||
import net.Chipperfluff.chipi.command.ChpCommand;
|
||||
import net.Chipperfluff.chipi.command.CommandHandler;
|
||||
import net.Chipperfluff.chipi.effect.ChipiBlessingEvents;
|
||||
import net.Chipperfluff.chipi.effect.ChipiHungerHandler;
|
||||
import net.Chipperfluff.chipi.effect.ModEffects;
|
||||
import net.Chipperfluff.chipi.entity.ModEntities;
|
||||
import net.Chipperfluff.chipi.entity.SpawnLogic;
|
||||
import net.Chipperfluff.chipi.entity.custom.MepEntity;
|
||||
import net.Chipperfluff.chipi.item.ModItemGroups;
|
||||
import net.Chipperfluff.chipi.item.ModItems;
|
||||
import net.Chipperfluff.chipi.world.gen.ChipiDungeonGenerator;
|
||||
import net.Chipperfluff.chipi.server.ChipiServerEvents;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.biome.v1.BiomeModifications;
|
||||
import net.fabricmc.fabric.api.biome.v1.BiomeSelectors;
|
||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.structure.StructurePlacementData;
|
||||
import net.minecraft.structure.StructureTemplate;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.GameRules;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.GenerationStep;
|
||||
import net.Chipperfluff.chipi.command.CommandHandler;
|
||||
|
||||
public class ChipiMod implements ModInitializer {
|
||||
|
||||
public static final String MOD_ID = "chipi";
|
||||
|
||||
public static final RegistryKey<World> CHIPI_DIMENSION_KEY = RegistryKey.of(RegistryKeys.WORLD, new Identifier("chipi", "chipi_dimension"));
|
||||
|
||||
private static final Identifier SPAWN_STRUCTURE = new Identifier("chipi", "spawn");
|
||||
|
||||
private static MinecraftServer SERVER;
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
|
||||
ModBlocks.register();
|
||||
ModItems.register();
|
||||
ModItemGroups.register();
|
||||
ModCriteria.register();
|
||||
ModEntities.register();
|
||||
ModEffects.register();
|
||||
ModCriteria.register();
|
||||
|
||||
ChipiBlessingEvents.register();
|
||||
ChipiHungerHandler.register();
|
||||
SpawnLogic.register();
|
||||
|
||||
CommandHandler.register();
|
||||
|
||||
FabricDefaultAttributeRegistry.register(ModEntities.MEP, MepEntity.createMepAttributes());
|
||||
|
||||
BiomeModifications.addFeature(
|
||||
BiomeSelectors.foundInOverworld(),
|
||||
GenerationStep.Feature.UNDERGROUND_ORES,
|
||||
RegistryKey.of(RegistryKeys.PLACED_FEATURE, new Identifier("chipi", "chipper_ore"))
|
||||
);
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTED.register(server -> {
|
||||
SERVER = server;
|
||||
});
|
||||
|
||||
ServerTickEvents.END_WORLD_TICK.register(world -> {
|
||||
if (!world.getRegistryKey().equals(CHIPI_DIMENSION_KEY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (PlayerEntity player : world.getPlayers()) {
|
||||
if (player.getBlockY() >= 50) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ChipperPortalBlock.teleportToChipiSpawn(world, player);
|
||||
}
|
||||
});
|
||||
|
||||
ServerWorldEvents.LOAD.register((server, world) -> {
|
||||
if (!world.getRegistryKey().equals(CHIPI_DIMENSION_KEY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
world.setTimeOfDay(18000);
|
||||
world.getGameRules()
|
||||
.get(GameRules.DO_DAYLIGHT_CYCLE)
|
||||
.set(false, server);
|
||||
|
||||
SpawnPlacedState state = world.getPersistentStateManager().getOrCreate(
|
||||
SpawnPlacedState::fromNbt,
|
||||
SpawnPlacedState::new,
|
||||
"chipi_spawn"
|
||||
);
|
||||
|
||||
if (state.placed) {
|
||||
return;
|
||||
}
|
||||
|
||||
StructureTemplate spawnTemplate = world.getStructureTemplateManager().getTemplate(SPAWN_STRUCTURE).orElse(null);
|
||||
|
||||
if (spawnTemplate == null) {
|
||||
System.err.println("[CHIPI] spawn.nbt not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
BlockPos spawnCenter = new BlockPos(0, 80, 0);
|
||||
|
||||
spawnTemplate.place(world, spawnCenter, spawnCenter, new StructurePlacementData(), world.getRandom(), 2);
|
||||
|
||||
world.setSpawnPos(spawnCenter.up(), 0.0f);
|
||||
|
||||
ChipiDungeonGenerator.generateInitialLayout(world, spawnCenter);
|
||||
|
||||
state.placed = true;
|
||||
state.markDirty();
|
||||
|
||||
System.out.println("[CHIPI] Spawn + initial dungeon generated");
|
||||
});
|
||||
}
|
||||
|
||||
public static ServerWorld getChipiWorld() {
|
||||
if (SERVER == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return SERVER.getWorld(CHIPI_DIMENSION_KEY);
|
||||
ChipiServerEvents.register();
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,16 +52,26 @@ public class ChipperPortalBlock extends Block {
|
||||
public static void teleportToChipiSpawn(ServerWorld targetWorld, PlayerEntity player) {
|
||||
BlockPos spawn = resolveSafeSpawn(targetWorld);
|
||||
|
||||
player.setVelocity(0.0, 0.0, 0.0);
|
||||
player.fallDistance = 0.0f;
|
||||
player.setOnGround(true);
|
||||
|
||||
player.teleport(
|
||||
targetWorld,
|
||||
spawn.getX() + 0.5,
|
||||
spawn.getY(),
|
||||
spawn.getZ() + 0.5,
|
||||
EnumSet.noneOf(PositionFlag.class),
|
||||
player.getYaw(),
|
||||
player.getPitch());
|
||||
targetWorld,
|
||||
spawn.getX() + 0.5,
|
||||
spawn.getY(),
|
||||
spawn.getZ() + 0.5,
|
||||
EnumSet.noneOf(PositionFlag.class),
|
||||
player.getYaw(),
|
||||
player.getPitch()
|
||||
);
|
||||
|
||||
player.setVelocity(0.0, 0.0, 0.0);
|
||||
player.fallDistance = 0.0f;
|
||||
player.setOnGround(true);
|
||||
}
|
||||
|
||||
|
||||
public static BlockPos resolveSafeSpawn(ServerWorld targetWorld) {
|
||||
BlockPos spawn = DEFAULT_SPAWN;
|
||||
BlockPos under = spawn.down();
|
||||
|
||||
@ -12,5 +12,6 @@ public class ChipiClient implements ClientModInitializer {
|
||||
public void onInitializeClient() {
|
||||
BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.CHIPPER_PORTAL, RenderLayer.getTranslucent());
|
||||
ModEntityRenderers.register();
|
||||
ModTooltips.register();
|
||||
}
|
||||
}
|
||||
|
||||
63
src/main/java/net/Chipperfluff/chipi/client/ModTooltips.java
Normal file
63
src/main/java/net/Chipperfluff/chipi/client/ModTooltips.java
Normal file
@ -0,0 +1,63 @@
|
||||
package net.Chipperfluff.chipi.client;
|
||||
|
||||
import net.Chipperfluff.chipi.block.ModBlocks;
|
||||
import net.Chipperfluff.chipi.item.ModItems;
|
||||
import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public final class ModTooltips {
|
||||
|
||||
private ModTooltips() {
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
|
||||
ItemTooltipCallback.EVENT.register((stack, context, lines) -> {
|
||||
|
||||
// ===== BLOCK ITEMS =====
|
||||
if (stack.isOf(ModBlocks.VOID_BLOCK.asItem()))
|
||||
lines.add(Text.translatable("tooltip.chipi.void_block"));
|
||||
|
||||
if (stack.isOf(ModBlocks.CHIPPER_FRAME.asItem()))
|
||||
lines.add(Text.translatable("tooltip.chipi.chipper_frame"));
|
||||
|
||||
if (stack.isOf(ModBlocks.CHIPPER_PORTAL.asItem()))
|
||||
lines.add(Text.translatable("tooltip.chipi.chipper_portal"));
|
||||
|
||||
if (stack.isOf(ModBlocks.CHIPPER_ORE.asItem()))
|
||||
lines.add(Text.translatable("tooltip.chipi.chipper_ore"));
|
||||
|
||||
if (stack.isOf(ModBlocks.CHIPPER_ALLOY_BLOCK.asItem()))
|
||||
lines.add(Text.translatable("tooltip.chipi.chipper_alloy_block"));
|
||||
|
||||
// ===== ITEMS =====
|
||||
if (stack.isOf(ModItems.NUT))
|
||||
lines.add(Text.translatable("tooltip.chipi.nut"));
|
||||
|
||||
if (stack.isOf(ModItems.RAW_CHIPPER_ORE))
|
||||
lines.add(Text.translatable("tooltip.chipi.raw_chipper_ore"));
|
||||
|
||||
if (stack.isOf(ModItems.CHIPPER_INGOT))
|
||||
lines.add(Text.translatable("tooltip.chipi.chipper_ingot"));
|
||||
|
||||
if (stack.isOf(ModItems.CHIPPER_ALLOY))
|
||||
lines.add(Text.translatable("tooltip.chipi.chipper_alloy"));
|
||||
|
||||
if (stack.isOf(ModItems.MEP_SPAWN_EGG))
|
||||
lines.add(Text.translatable("tooltip.chipi.mep_spawn_egg"));
|
||||
|
||||
// ===== ARMOR =====
|
||||
if (stack.isOf(ModItems.CHIPPER_HELMET))
|
||||
lines.add(Text.translatable("tooltip.chipi.chipper_helmet"));
|
||||
|
||||
if (stack.isOf(ModItems.CHIPPER_CHESTPLATE))
|
||||
lines.add(Text.translatable("tooltip.chipi.chipper_chestplate"));
|
||||
|
||||
if (stack.isOf(ModItems.CHIPPER_LEGGINGS))
|
||||
lines.add(Text.translatable("tooltip.chipi.chipper_leggings"));
|
||||
|
||||
if (stack.isOf(ModItems.CHIPPER_BOOTS))
|
||||
lines.add(Text.translatable("tooltip.chipi.chipper_boots"));
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,26 +1,28 @@
|
||||
package net.Chipperfluff.chipi.entity;
|
||||
|
||||
import net.Chipperfluff.chipi.ChipiMod;
|
||||
import net.Chipperfluff.chipi.entity.custom.MepEntity;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder;
|
||||
|
||||
import net.minecraft.entity.EntityDimensions;
|
||||
import net.minecraft.entity.SpawnGroup;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class ModEntities {
|
||||
public final class ModEntities {
|
||||
|
||||
public static final EntityType<MepEntity> MEP = Registry.register(
|
||||
Registries.ENTITY_TYPE,
|
||||
new Identifier(ChipiMod.MOD_ID, "mep"),
|
||||
FabricEntityTypeBuilder.createMob()
|
||||
.entityFactory(MepEntity::new)
|
||||
.dimensions(EntityDimensions.fixed(0.6f, 1.95f))
|
||||
.build()
|
||||
);
|
||||
public static final EntityType<MepEntity> MEP =
|
||||
Registry.register(
|
||||
Registries.ENTITY_TYPE,
|
||||
new Identifier("chipi", "mep"),
|
||||
FabricEntityTypeBuilder
|
||||
.create(SpawnGroup.CREATURE, MepEntity::new)
|
||||
.dimensions(EntityDimensions.fixed(0.6f, 1.95f))
|
||||
.build()
|
||||
);
|
||||
|
||||
public static void register() {
|
||||
// called from mod init
|
||||
private ModEntities() {
|
||||
}
|
||||
}
|
||||
|
||||
61
src/main/java/net/Chipperfluff/chipi/entity/SpawnLogic.java
Normal file
61
src/main/java/net/Chipperfluff/chipi/entity/SpawnLogic.java
Normal file
@ -0,0 +1,61 @@
|
||||
package net.Chipperfluff.chipi.entity;
|
||||
|
||||
import net.fabricmc.fabric.api.biome.v1.BiomeModifications;
|
||||
import net.fabricmc.fabric.api.biome.v1.BiomeSelectors;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.SpawnGroup;
|
||||
import net.minecraft.entity.SpawnReason;
|
||||
import net.minecraft.entity.SpawnRestriction;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.world.Heightmap;
|
||||
import net.minecraft.world.ServerWorldAccess;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
public final class SpawnLogic {
|
||||
|
||||
private static final RegistryKey<Biome> VOID_BIOME =
|
||||
RegistryKey.of(RegistryKeys.BIOME, new Identifier("chipi", "void"));
|
||||
|
||||
private SpawnLogic() {
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
|
||||
BiomeModifications.addSpawn(
|
||||
BiomeSelectors.includeByKey(VOID_BIOME),
|
||||
SpawnGroup.MONSTER,
|
||||
ModEntities.MEP,
|
||||
10,
|
||||
1,
|
||||
4
|
||||
);
|
||||
|
||||
SpawnRestriction.register(
|
||||
ModEntities.MEP,
|
||||
SpawnRestriction.Location.ON_GROUND,
|
||||
Heightmap.Type.MOTION_BLOCKING_NO_LEAVES,
|
||||
SpawnLogic::canSpawn
|
||||
);
|
||||
}
|
||||
|
||||
private static boolean canSpawn(EntityType<? extends MobEntity> type, ServerWorldAccess world, SpawnReason reason, BlockPos pos, Random random) {
|
||||
int y = pos.getY();
|
||||
if (y < 87 || y > 90) return false;
|
||||
if (pos.getZ() < 18) return false;
|
||||
|
||||
BlockState below = world.getBlockState(pos.down());
|
||||
boolean can_spawn = below.isOf(Blocks.POLISHED_BLACKSTONE_BRICKS);
|
||||
|
||||
System.out.println("[MEP ENTITY] spawn check pos=" + pos + " below=" + below.getBlock());
|
||||
|
||||
return can_spawn;
|
||||
}
|
||||
}
|
||||
@ -22,7 +22,10 @@ import net.minecraft.world.World;
|
||||
|
||||
public class MepEntity extends PathAwareEntity {
|
||||
|
||||
private static final int FORGET_TARGET_AFTER_TICKS = 100;
|
||||
|
||||
private boolean angryAtPlayer = false;
|
||||
private int ticksSinceLastSeen = 0;
|
||||
|
||||
public MepEntity(EntityType<? extends PathAwareEntity> entityType, World world) {
|
||||
super(entityType, world);
|
||||
@ -42,7 +45,7 @@ public class MepEntity extends PathAwareEntity {
|
||||
this,
|
||||
PlayerEntity.class,
|
||||
true,
|
||||
target -> target instanceof PlayerEntity player && (angryAtPlayer || !isPlayerProtected(player))
|
||||
target -> target instanceof PlayerEntity player && !isPlayerProtected(player)
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -51,13 +54,15 @@ public class MepEntity extends PathAwareEntity {
|
||||
return PathAwareEntity.createMobAttributes()
|
||||
.add(EntityAttributes.GENERIC_MAX_HEALTH, 20.0)
|
||||
.add(EntityAttributes.GENERIC_ATTACK_DAMAGE, 4.0)
|
||||
.add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.25);
|
||||
.add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.25)
|
||||
.add(EntityAttributes.GENERIC_FOLLOW_RANGE, 32.0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean damage(DamageSource source, float amount) {
|
||||
if (source.getAttacker() instanceof PlayerEntity) {
|
||||
angryAtPlayer = true;
|
||||
ticksSinceLastSeen = 0;
|
||||
}
|
||||
return super.damage(source, amount);
|
||||
}
|
||||
@ -68,18 +73,39 @@ public class MepEntity extends PathAwareEntity {
|
||||
|
||||
LivingEntity target = this.getTarget();
|
||||
|
||||
if (angryAtPlayer) {
|
||||
if (!(target instanceof PlayerEntity) || !this.canSee(target)) {
|
||||
angryAtPlayer = false;
|
||||
this.setTarget(null);
|
||||
}
|
||||
if (!(target instanceof PlayerEntity player)) {
|
||||
ticksSinceLastSeen = 0;
|
||||
angryAtPlayer = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (target instanceof PlayerEntity player && isPlayerProtected(player)) {
|
||||
this.setTarget(null);
|
||||
this.getNavigation().stop();
|
||||
// Protected players instantly cancel targeting
|
||||
if (isPlayerProtected(player)) {
|
||||
clearTarget();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.canSee(player)) {
|
||||
ticksSinceLastSeen = 0;
|
||||
angryAtPlayer = true;
|
||||
this.getNavigation().startMovingTo(player, 1.2D);
|
||||
} else {
|
||||
ticksSinceLastSeen++;
|
||||
|
||||
// Keep chasing for a while even without LOS
|
||||
if (ticksSinceLastSeen <= FORGET_TARGET_AFTER_TICKS) {
|
||||
this.getNavigation().startMovingTo(player, 1.2D);
|
||||
} else {
|
||||
clearTarget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void clearTarget() {
|
||||
angryAtPlayer = false;
|
||||
ticksSinceLastSeen = 0;
|
||||
this.setTarget(null);
|
||||
this.getNavigation().stop();
|
||||
}
|
||||
|
||||
private static boolean isPlayerProtected(PlayerEntity player) {
|
||||
@ -90,6 +116,19 @@ public class MepEntity extends PathAwareEntity {
|
||||
return false;
|
||||
}
|
||||
|
||||
return state.getBlock() instanceof StairsBlock || state.getBlock() instanceof SlabBlock;
|
||||
return state.getBlock() instanceof StairsBlock
|
||||
|| state.getBlock() instanceof SlabBlock;
|
||||
}
|
||||
|
||||
// === Despawn prevention ===
|
||||
|
||||
@Override
|
||||
public boolean cannotDespawn() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canImmediatelyDespawn(double distanceSquared) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,115 @@
|
||||
package net.Chipperfluff.chipi.server;
|
||||
|
||||
import net.Chipperfluff.chipi.block.ChipperPortalBlock;
|
||||
import net.Chipperfluff.chipi.world.gen.ChipiDungeonGenerator;
|
||||
import net.Chipperfluff.chipi.SpawnPlacedState;
|
||||
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.structure.StructurePlacementData;
|
||||
import net.minecraft.structure.StructureTemplate;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.GameRules;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public final class ChipiServerEvents {
|
||||
|
||||
public static final RegistryKey<World> CHIPI_DIMENSION_KEY =
|
||||
RegistryKey.of(RegistryKeys.WORLD, new Identifier("chipi", "chipi_dimension"));
|
||||
|
||||
private static final Identifier SPAWN_STRUCTURE =
|
||||
new Identifier("chipi", "spawn");
|
||||
|
||||
private static MinecraftServer SERVER;
|
||||
|
||||
private ChipiServerEvents() {}
|
||||
|
||||
public static void register() {
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTED.register(server -> {
|
||||
SERVER = server;
|
||||
});
|
||||
|
||||
ServerTickEvents.END_WORLD_TICK.register(ChipiServerEvents::handleVoidFailsafe);
|
||||
|
||||
ServerWorldEvents.LOAD.register(ChipiServerEvents::onWorldLoad);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Tick logic
|
||||
// ============================================================
|
||||
private static void handleVoidFailsafe(ServerWorld world) {
|
||||
if (!world.getRegistryKey().equals(CHIPI_DIMENSION_KEY)) return;
|
||||
|
||||
for (PlayerEntity player : world.getPlayers()) {
|
||||
if (player.getBlockY() >= 50) continue;
|
||||
ChipperPortalBlock.teleportToChipiSpawn(world, player);
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// World init
|
||||
// ============================================================
|
||||
private static void onWorldLoad(MinecraftServer server, ServerWorld world) {
|
||||
if (!world.getRegistryKey().equals(CHIPI_DIMENSION_KEY)) return;
|
||||
|
||||
world.setTimeOfDay(18000);
|
||||
world.getGameRules()
|
||||
.get(GameRules.DO_DAYLIGHT_CYCLE)
|
||||
.set(false, server);
|
||||
|
||||
SpawnPlacedState state = world.getPersistentStateManager().getOrCreate(
|
||||
SpawnPlacedState::fromNbt,
|
||||
SpawnPlacedState::new,
|
||||
"chipi_spawn"
|
||||
);
|
||||
|
||||
if (state.placed) return;
|
||||
|
||||
StructureTemplate spawnTemplate =
|
||||
world.getStructureTemplateManager()
|
||||
.getTemplate(SPAWN_STRUCTURE)
|
||||
.orElse(null);
|
||||
|
||||
if (spawnTemplate == null) {
|
||||
System.err.println("[CHIPI] spawn.nbt not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
BlockPos spawnCenter = new BlockPos(0, 80, 0);
|
||||
|
||||
spawnTemplate.place(
|
||||
world,
|
||||
spawnCenter,
|
||||
spawnCenter,
|
||||
new StructurePlacementData(),
|
||||
world.getRandom(),
|
||||
2
|
||||
);
|
||||
|
||||
world.setSpawnPos(spawnCenter.up(), 0.0f);
|
||||
|
||||
ChipiDungeonGenerator.generateInitialLayout(world, spawnCenter);
|
||||
|
||||
state.placed = true;
|
||||
state.markDirty();
|
||||
|
||||
System.out.println("[CHIPI] Spawn + initial dungeon generated");
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Access
|
||||
// ============================================================
|
||||
public static ServerWorld getChipiWorld() {
|
||||
if (SERVER == null) return null;
|
||||
return SERVER.getWorld(CHIPI_DIMENSION_KEY);
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,8 @@
|
||||
|
||||
"effect.chipi.chipi_blessing": "Chipi's Blessing",
|
||||
|
||||
"entity.chipi.mep": "Merp :3",
|
||||
|
||||
"block.chipi.void_block": "Void Block",
|
||||
"block.chipi.chipper_frame": "Chipper Frame",
|
||||
"block.chipi.chipper_portal": "Chipper Portal",
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"downfall": 0,
|
||||
"has_precipitation": false,
|
||||
"temperature_modifier": "frozen",
|
||||
"creature_spawn_probability": 0,
|
||||
"creature_spawn_probability": 0.1,
|
||||
"effects": {
|
||||
"sky_color": 0,
|
||||
"fog_color": 0,
|
||||
@ -13,7 +13,15 @@
|
||||
"foliage_color": 0,
|
||||
"grass_color_modifier": "none"
|
||||
},
|
||||
"spawners": {},
|
||||
"spawners": {
|
||||
"monster": [],
|
||||
"creature": [],
|
||||
"ambient": [],
|
||||
"axolotls": [],
|
||||
"underground_water_creature": [],
|
||||
"water_creature": [],
|
||||
"water_ambient": []
|
||||
},
|
||||
"spawn_costs": {},
|
||||
"carvers": {},
|
||||
"features": []
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user