So another blackout doesn't make me lose a day's worth of dev time since I couldn't push stuff.

This commit is contained in:
Waterpicker 2023-09-07 20:20:03 -05:00
parent bd6ef88c06
commit c1e3b6b5d8
14 changed files with 232 additions and 21 deletions

View file

@ -61,6 +61,7 @@ import org.dimdev.dimdoors.sound.ModSoundEvents;
import org.dimdev.dimdoors.util.schematic.SchemFixer;
import org.dimdev.dimdoors.world.ModBiomes;
import org.dimdev.dimdoors.world.ModDimensions;
import org.dimdev.dimdoors.world.ModStructures;
import org.dimdev.dimdoors.world.decay.DecayPredicate;
import org.dimdev.dimdoors.world.decay.DecayProcessor;
import org.dimdev.dimdoors.world.decay.Decay;
@ -122,6 +123,7 @@ public class DimensionalDoors {
ModFeatures.init();
ModBiomes.init();
ModDimensions.init();
ModStructures.init();
ModStats.init();
ModBlockEntityTypes.init();
ModCommands.init();

View file

@ -1,2 +1,20 @@
package org.dimdev.dimdoors.mixin;public interface NetherFortressPiecesAccessor {
package org.dimdev.dimdoors.mixin;
import net.minecraft.world.level.levelgen.structure.structures.NetherFortressPieces;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(NetherFortressPieces.class)
public interface NetherFortressPiecesAccessor {
@Accessor("BRIDGE_PIECE_WEIGHTS")
public static NetherFortressPieces.PieceWeight[] getBridgePieceWeights() {
throw new AssertionError("Untransformed @Accessor");
}
@Accessor("BRIDGE_PIECE_WEIGHTS")
@Mutable
public static void setBridgePieceWeights(NetherFortressPieces.PieceWeight[] pieceWeights) {
throw new AssertionError("Untransformed @Accessor");
}
}

View file

@ -4,7 +4,6 @@ import net.minecraft.core.Direction;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.levelgen.structure.StructurePieceAccessor;
import net.minecraft.world.level.levelgen.structure.structures.NetherFortressPieces;
import org.dimdev.dimdoors.world.feature.NetherPiecesRegistry;
import org.dimdev.dimdoors.world.structure.NetherGatewayPiece;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
@ -16,7 +15,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Arrays;
@Mixin(NetherFortressPieces.class)
public class NetherFortressPiecesMixin implements NetherPiecesRegistry {
public class NetherFortressPiecesMixin {
@Inject(method = "findAndCreateBridgePieceFactory", at = @At("HEAD"), cancellable = true)
private static void findAndCreateBridgePieceFactory(NetherFortressPieces.PieceWeight weight, StructurePieceAccessor pieces, RandomSource random, int x, int y, int z, Direction orientation, int genDepth, CallbackInfoReturnable<NetherFortressPieces.NetherBridgePiece> cir) {
if (weight.pieceClass == NetherGatewayPiece.class) {

View file

@ -4,7 +4,9 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import org.dimdev.dimdoors.DimensionalDoors;
import org.dimdev.dimdoors.rift.registry.LinkProperties;
import org.dimdev.dimdoors.rift.targets.DungeonTarget;
import org.dimdev.dimdoors.rift.targets.PocketEntranceMarker;
import org.dimdev.dimdoors.rift.targets.RandomTarget;
import org.dimdev.dimdoors.rift.targets.VirtualTarget;
@ -72,7 +74,8 @@ public interface DefaultDungeonDestinations { // TODO: lower weights?
}
static VirtualTarget getGateway() {
return RandomTarget.builder()
return DungeonTarget.builder()
.dungeonGroup(DimensionalDoors.id("dungeon"))
.acceptedGroups(Collections.singleton(0))
.coordFactor(1)
.negativeDepthFactor(Double.POSITIVE_INFINITY)

View file

@ -25,17 +25,16 @@ public interface VirtualPocket extends Weighted<PocketGenerationContext>, Refere
//TODO: split up in ImplementedVirtualPocket and VirtualPocketList
static VirtualPocket deserialize(Tag nbt, @Nullable ResourceManager manager) {
switch (nbt.getId()) {
case Tag.TAG_LIST: // It's a list of VirtualPocket
return VirtualPocketList.deserialize((ListTag) nbt, manager);
case Tag.TAG_COMPOUND: // It's a serialized VirtualPocket
return ImplementedVirtualPocket.deserialize((CompoundTag) nbt, manager);
return switch (nbt.getId()) {
case Tag.TAG_LIST -> // It's a list of VirtualPocket
VirtualPocketList.deserialize((ListTag) nbt, manager);
case Tag.TAG_COMPOUND -> // It's a serialized VirtualPocket
ImplementedVirtualPocket.deserialize((CompoundTag) nbt, manager);
// TODO: throw if manager is null
case Tag.TAG_STRING: // It's a reference to a resource location
return ResourceUtil.loadReferencedResource(manager, RESOURCE_STARTING_PATH, nbt.getAsString(), ResourceUtil.NBT_READER.andThenComposable(nbtElement -> deserialize(nbtElement, manager)));
default:
throw new RuntimeException(String.format("Unexpected NbtType %d!", nbt.getId()));
}
case Tag.TAG_STRING -> // It's a reference to a resource location
ResourceUtil.loadReferencedResource(manager, RESOURCE_STARTING_PATH, nbt.getAsString(), ResourceUtil.NBT_READER.andThenComposable(nbtElement -> deserialize(nbtElement, manager)));
default -> throw new RuntimeException(String.format("Unexpected NbtType %d!", nbt.getId()));
};
}
static Tag serialize(VirtualPocket virtualPocket, boolean allowReference) {

View file

@ -67,8 +67,9 @@ public class DungeonTarget extends RandomTarget {
DungeonTargetBuilder() {
}
public void dungeonGroup(ResourceLocation dungeonGroup) {
public DungeonTargetBuilder dungeonGroup(ResourceLocation dungeonGroup) {
this.dungeonGroup = dungeonGroup;
return this;
}
@Override

View file

@ -151,7 +151,7 @@ public class RandomTarget extends VirtualTarget { // TODO: Split into DungeonTar
// Make a new dungeon pocket
RiftBlockEntity thisRift = (RiftBlockEntity) this.location.getBlockEntity();
LinkProperties newLink = thisRift.getProperties() != null ? thisRift.getProperties().toBuilder().linksRemaining(0).build() : null;
Pocket pocket = PocketGenerator.generateDungeonPocketV2(virtualLocation, new GlobalReference(!this.noLinkBack ? this.location : null), newLink); // TODO make the generated dungeon of the same type, but in the overworld
Pocket pocket = generatePocket(virtualLocation, new GlobalReference(!this.noLinkBack ? this.location : null), newLink); // TODO make the generated dungeon of the same type, but in the overworld
// Link the rift if necessary and teleport the entity
if (!this.noLink)

View file

@ -1,2 +1,48 @@
package org.dimdev.dimdoors.world;public class ModStructures {
package org.dimdev.dimdoors.world;
import dev.architectury.registry.registries.Registrar;
import dev.architectury.registry.registries.RegistrarManager;
import dev.architectury.registry.registries.RegistrySupplier;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceType;
import net.minecraft.world.level.levelgen.structure.structures.NetherFortressPieces;
import org.dimdev.dimdoors.DimensionalDoors;
import org.dimdev.dimdoors.mixin.NetherFortressPiecesAccessor;
import org.dimdev.dimdoors.world.structure.NetherGatewayPiece;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.function.Supplier;
import static org.dimdev.dimdoors.mixin.NetherFortressPiecesAccessor.getBridgePieceWeights;
public class ModStructures {
public static Registrar<StructurePieceType> STRUCTURE_PIECE_TYPES = RegistrarManager.get(DimensionalDoors.MOD_ID).get(Registries.STRUCTURE_PIECE);
public static final RegistrySupplier<StructurePieceType> NETHER_GATEWAY = registerNetherBridge("nether_fortress_gateway", NetherGatewayPiece.class, 5, 1);
private static RegistrySupplier<StructurePieceType> registerNetherBridge(String name, Class<NetherGatewayPiece> netherGatewayPieceClass, int weight, int count) {
addNetherBridgeWeight(netherGatewayPieceClass, weight, count);
return registerContextless(name, () -> (StructurePieceType.ContextlessType) compoundTag -> {
try {
return netherGatewayPieceClass.getConstructor(CompoundTag.class).newInstance(compoundTag);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
});
}
private static void addNetherBridgeWeight(Class<NetherGatewayPiece> netherGatewayPieceClass, int weight, int count) {
var array = Arrays.copyOf(NetherFortressPiecesAccessor.getBridgePieceWeights(), NetherFortressPiecesAccessor.getBridgePieceWeights().length + 1);
array[array.length - 1] = new NetherFortressPieces.PieceWeight(netherGatewayPieceClass, weight, count);
NetherFortressPiecesAccessor.setBridgePieceWeights(array);
}
private static RegistrySupplier<StructurePieceType> registerContextless(String name, Supplier<StructurePieceType> supplier) {
return STRUCTURE_PIECE_TYPES.register(DimensionalDoors.id(name), supplier);
}
public static void init() {
}
}

View file

@ -11,7 +11,7 @@ public class SchematicGatewayFeature extends Feature<SchematicGatewayFeatureConf
@Override
public boolean place(FeaturePlaceContext<SchematicGatewayFeatureConfig> featureContext) {
if (featureContext.level().isEmptyBlock(featureContext.origin()) && featureContext.config().getGateway().test(featureContext.level(), featureContext.origin())) {
if (featureContext.config().getGateway().test(featureContext.level(), featureContext.origin())) {
featureContext.config().getGateway().generate(featureContext.level(), featureContext.origin());
return true;
}

View file

@ -0,0 +1,133 @@
package org.dimdev.dimdoors.world.structure;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.StructureManager;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.StairBlock;
import net.minecraft.world.level.block.state.properties.Half;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.level.levelgen.structure.StructurePieceAccessor;
import net.minecraft.world.level.levelgen.structure.structures.NetherFortressPieces;
import org.dimdev.dimdoors.block.ModBlocks;
import org.dimdev.dimdoors.block.entity.ModBlockEntityTypes;
import org.dimdev.dimdoors.pockets.DefaultDungeonDestinations;
import org.dimdev.dimdoors.rift.targets.DungeonTarget;
import org.dimdev.dimdoors.world.ModStructures;
public class NetherGatewayPiece extends NetherFortressPieces.NetherBridgePiece {
public NetherGatewayPiece(int genDepth, BoundingBox boundingBox, Direction orientation) {
super(ModStructures.NETHER_GATEWAY.get(), genDepth, boundingBox);
setOrientation(orientation);
}
public NetherGatewayPiece(CompoundTag tag) {
super(ModStructures.NETHER_GATEWAY.get(), tag);
}
public static NetherGatewayPiece createPieces(StructurePieceAccessor pieces, int x, int y, int z, int genDepth, Direction orientation) {
BoundingBox boundingBox = BoundingBox.orientBox(x, y, z, -2, 0, 0, 7,8, 7, orientation);
if (!isOkBox(boundingBox) || pieces.findCollisionPiece(boundingBox) != null) return null;
else return new NetherGatewayPiece(genDepth, boundingBox, orientation);
}
@Override
public void postProcess(WorldGenLevel level, StructureManager structureManager, ChunkGenerator generator, RandomSource random, BoundingBox box, ChunkPos chunkPos, BlockPos pos) {
var airstate = Blocks.AIR.defaultBlockState();
var netherBrickFenceState = Blocks.NETHER_BRICK_FENCE.defaultBlockState();
var netherBrickState = Blocks.NETHER_BRICKS.defaultBlockState();
var netherSlabState = Blocks.NETHER_BRICK_SLAB.defaultBlockState();
// Set all the blocks in the area of the room to air
generateBox(level, box, 0, 2, 0, 6, 6, 6, airstate, airstate, false);
// Set up the platform under the gateway
generateBox(level, box, 0, 0, 0, 6, 1, 6, netherBrickState, netherBrickState, false);
// Build the fence at the back of the room
generateBox(level, box, 1, 2, 6, 5, 2, 6, netherBrickState, netherBrickState, false);
generateBox(level, box, 1, 3, 6, 5, 3, 6, netherBrickFenceState, netherBrickFenceState, false);
// Build the fences at the sides of the room
generateBox(level, box, 0, 2, 0, 0, 2, 6, netherBrickState, netherBrickState, false);
generateBox(level, box, 0, 3, 0, 0, 3, 6, netherBrickFenceState, netherBrickFenceState, false);
generateBox(level, box, 6, 2, 0, 6, 2, 6, netherBrickState, netherBrickState, false);
generateBox(level, box, 6, 3, 0, 6, 3, 6, netherBrickFenceState, netherBrickFenceState, false);
// Build the fence portions closest to the entrance
placeBlock(level, netherBrickState, 1, 2, 0, box);
placeBlock(level, netherBrickFenceState, 1, 3, 0, box);
placeBlock(level, netherBrickState, 5, 2, 0, box);
placeBlock(level, netherBrickFenceState, 5, 3, 0, box);
// Build the first layer of the gateway
generateBox(level, box, 1, 2, 2, 5, 2, 5, netherBrickState, netherBrickState, false);
generateBox(level, box, 1, 2, 1, 5, 2, 1, netherSlabState, netherSlabState, false);
placeBlock(level, netherSlabState, 1, 2, 2, box);
placeBlock(level, netherSlabState, 5, 2, 2, box);
// Build the second layer of the gateway
var stairs = Blocks.NETHER_BRICK_STAIRS.defaultBlockState().setValue(StairBlock.FACING, Direction.SOUTH);
generateBox(level, box, 2, 3, 3, 2, 3, 4, netherBrickState, netherBrickState, false);
generateBox(level, box, 4, 3, 3, 4, 3, 4, netherBrickState, netherBrickState, false);
placeBlock(level, netherBrickState, 3, 3, 4, box);
placeBlock(level, stairs, 3, 3, 5, box);
// Build the third layer of the gateway
// We add 4 to get the rotated metadata for upside-down stairs
// because Minecraft only supports metadata rotations for normal stairs -_-
generateBox(level, box, 2, 4, 4, 4, 4, 4, stairs, stairs, false);
placeBlock(level, Blocks.NETHER_BRICK_STAIRS.defaultBlockState().setValue(StairBlock.HALF, Half.TOP).setValue(StairBlock.FACING, Direction.SOUTH), 2, 4, 3, box);
placeBlock(level, Blocks.NETHER_BRICK_STAIRS.defaultBlockState().setValue(StairBlock.HALF, Half.TOP).setValue(StairBlock.FACING, Direction.WEST), 4, 4, 3, box);
// Build the fourth layer of the gateway
placeBlock(level, netherBrickState, 3, 5, 3, box);
placeBlock(level, Blocks.NETHERRACK.defaultBlockState(), 2, 5, 3, box);
placeBlock(level, Blocks.NETHER_BRICK_STAIRS.defaultBlockState().setValue(StairBlock.HALF, Half.TOP).setValue(StairBlock.FACING, Direction.EAST), 1, 5, 3, box);
placeBlock(level, Blocks.NETHER_BRICK_STAIRS.defaultBlockState().setValue(StairBlock.HALF, Half.TOP).setValue(StairBlock.FACING, Direction.NORTH), 2, 5, 2, box);
placeBlock(level, Blocks.NETHER_BRICK_STAIRS.defaultBlockState().setValue(StairBlock.HALF, Half.TOP).setValue(StairBlock.FACING, Direction.SOUTH), 2, 5, 4, box);
placeBlock(level, Blocks.NETHERRACK.defaultBlockState(), 4, 5, 3, box);
placeBlock(level, Blocks.NETHER_BRICK_STAIRS.defaultBlockState().setValue(StairBlock.HALF, Half.TOP).setValue(StairBlock.FACING, Direction.WEST), 5, 5, 3, box);
placeBlock(level, Blocks.NETHER_BRICK_STAIRS.defaultBlockState().setValue(StairBlock.HALF, Half.TOP).setValue(StairBlock.FACING, Direction.NORTH), 4, 5, 2, box);
placeBlock(level, Blocks.NETHER_BRICK_STAIRS.defaultBlockState().setValue(StairBlock.HALF, Half.TOP).setValue(StairBlock.FACING, Direction.SOUTH), 4, 5, 4, box);
// Build the top layer of the gateway
placeBlock(level, netherBrickFenceState, 3, 6, 3, box);
placeBlock(level, Blocks.FIRE.defaultBlockState(), 2, 6, 3, box);
placeBlock(level, netherBrickFenceState, 1, 6, 3, box);
placeBlock(level, netherBrickFenceState, 2, 6, 2, box);
placeBlock(level, netherBrickFenceState, 2, 6, 4, box);
placeBlock(level, Blocks.FIRE.defaultBlockState(), 4, 6, 3, box);
placeBlock(level, netherBrickFenceState, 5, 6, 3, box);
placeBlock(level, netherBrickFenceState, 4, 6, 2, box);
placeBlock(level, netherBrickFenceState, 4, 6, 4, box);
// Place the transient door
placeBlock(level, ModBlocks.DIMENSIONAL_PORTAL.get().defaultBlockState(), 3, 3, 3, box);
level.getBlockEntity(getWorldPos(3,3,3), ModBlockEntityTypes.ENTRANCE_RIFT.get()).ifPresent(rift -> {
rift.setProperties(DefaultDungeonDestinations.OVERWORLD_LINK_PROPERTIES);
rift.setDestination(DefaultDungeonDestinations.getGateway());
});
for (int x = 0; x <= 6; ++x)
{
for (int z = 0; z <= 6; ++z)
{
this.fillColumnDown(level, netherBrickState, x, -1, z, box);
}
}
}
}

View file

@ -1,16 +1,20 @@
{
"feature": "dimdoors:two_pillars",
"placement": [
{
"type": "minecraft:count",
"count": 1
},
{
"type": "minecraft:rarity_filter",
"chance": 200
"chance": 65
},
{
"type": "minecraft:in_square"
},
{
"type": "minecraft:heightmap",
"heightmap": "WORLD_SURFACE_WG"
"heightmap": "OCEAN_FLOOR_WG"
},
{
"type": "minecraft:biome"

View file

@ -12,6 +12,8 @@
"ExtendedServerPlayNetworkhandlerMixin",
"ItemMixin",
"ItemMixin$SettingsMixin",
"NetherFortressPiecesAccessor",
"NetherFortressPiecesMixin",
"PlayerEntityMixin",
"ServerPlayerEntityMixin",
"ServerPlayerInteractionManagerMixin",

View file

@ -38,4 +38,7 @@ accessible method net/minecraft/world/item/crafting/RecipeManager byType (Lnet/m
accessible method net/minecraft/world/item/crafting/ShapedRecipe dissolvePattern ([Ljava/lang/String;Ljava/util/Map;II)Lnet/minecraft/core/NonNullList;
accessible method net/minecraft/world/item/crafting/Ingredient valueFromJson (Lcom/google/gson/JsonObject;)Lnet/minecraft/world/item/crafting/Ingredient$Value;
accessible class net/minecraft/core/particles/SimpleParticleType
accessible class net/minecraft/core/particles/SimpleParticleType
accessible class net/minecraft/world/level/levelgen/structure/structures/NetherFortressPieces$NetherBridgePiece
accessible class net/minecraft/world/level/levelgen/structure/structures/NetherFortressPieces$PieceWeight

View file

@ -9,6 +9,7 @@ import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.dimension.DimensionType;
import org.dimdev.dimdoors.DimensionalDoors;
import org.dimdev.dimdoors.client.effect.DimensionSpecialEffectsExtensions;
import org.dimdev.dimdoors.client.effect.LimboDimensionEffect;