Conversation
012a7b3 to
8ef38ae
Compare
Roelymole
left a comment
There was a problem hiding this comment.
Here are a few thoughts to get you started. A big theme is avoiding using mixins where we don't need them.
b9ce6f2 to
aaa11f4
Compare
Roelymole
left a comment
There was a problem hiding this comment.
Here are a few more thoughts.
There was a problem hiding this comment.
Some of the lines in this file are indented too much, but like I said before, the Moon versions of vanilla animals don't really fit.
Again, they should probably be removed for now and we can come up with something that makes more later.
| public static boolean hasVillageAccessKey(Player player) { | ||
| Container accessories = player.galacticraft$getAccessories(); | ||
| for (int slot = 0; slot < accessories.getContainerSize(); ++slot) { | ||
| ItemStack stack = accessories.getItem(slot); | ||
| if (stack.is(GCItemTags.VILLAGE_ACCESS_KEYS)) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } |
There was a problem hiding this comment.
You should maybe also check whether the player has the key in one of their hands, in case they don't have enough room in their accessory slots.
| this.tag(ConventionalItemTags.VILLAGER_JOB_SITES) | ||
| .add(GCBlocks.LUNAR_CARTOGRAPHY_TABLE.asItem()); | ||
| .add(GCBlocks.LUNAR_CARTOGRAPHY_TABLE.asItem()) | ||
| .add(GCBlocks.LUNAR_WORKBENCH.asItem()) | ||
| .add(GCBlocks.LUNAR_SMITHING_TABLE.asItem()); |
There was a problem hiding this comment.
You have added the Lunar Cheese Press to the #c:villager_job_sites block tag, but not the item tag. I'm guessing this was just an oversight.
| // COMPACT MINERAL BLOCKS | ||
| this.block(GCBlocks.SILICON_BLOCK, "Block of Silicon"); | ||
| this.block(GCBlocks.METEORIC_IRON_BLOCK, "Block of Meteoric Iron"); | ||
| this.block(GCBlocks.METEORIC_IRON_DOOR, "Meteoric Iron Door"); |
There was a problem hiding this comment.
This translation doesn't really belong in the middle of all the compact mineral block translations e.g. "Block of ..."
It might be better to find somewhere else for it to go, such as the misc decor section.
| "NoiseBasedChunkGeneratorMixin", | ||
| "PlayerMixin", | ||
| "ServerLevelMixin", | ||
| "WalkNodeEvaluatorMixin", |
There was a problem hiding this comment.
These mixins are listed in alphabetical order, so "WalkNodeEvaluatorMixin" should be last.
| private void createTallDoorTop(BlockModelGenerators generator, Block topBlock, Block baseDoor) { | ||
| generator.blockStateOutput.accept(MultiVariantGenerator.multiVariant(topBlock).with(PropertyDispatch.properties(MeteoricIronDoorTopBlock.FACING, MeteoricIronDoorTopBlock.HINGE, MeteoricIronDoorTopBlock.OPEN) | ||
| .select(Direction.EAST, net.minecraft.world.level.block.state.properties.DoorHingeSide.LEFT, false, doorTopVariant(baseDoor, "_top_cap_left", VariantProperties.Rotation.R0)) | ||
| .select(Direction.EAST, net.minecraft.world.level.block.state.properties.DoorHingeSide.LEFT, true, doorTopVariant(baseDoor, "_top_cap_left_open", VariantProperties.Rotation.R90)) | ||
| .select(Direction.EAST, net.minecraft.world.level.block.state.properties.DoorHingeSide.RIGHT, false, doorTopVariant(baseDoor, "_top_cap_right", VariantProperties.Rotation.R0)) | ||
| .select(Direction.EAST, net.minecraft.world.level.block.state.properties.DoorHingeSide.RIGHT, true, doorTopVariant(baseDoor, "_top_cap_right_open", VariantProperties.Rotation.R270)) | ||
| .select(Direction.NORTH, net.minecraft.world.level.block.state.properties.DoorHingeSide.LEFT, false, doorTopVariant(baseDoor, "_top_cap_left", VariantProperties.Rotation.R270)) | ||
| .select(Direction.NORTH, net.minecraft.world.level.block.state.properties.DoorHingeSide.LEFT, true, doorTopVariant(baseDoor, "_top_cap_left_open", VariantProperties.Rotation.R0)) | ||
| .select(Direction.NORTH, net.minecraft.world.level.block.state.properties.DoorHingeSide.RIGHT, false, doorTopVariant(baseDoor, "_top_cap_right", VariantProperties.Rotation.R270)) | ||
| .select(Direction.NORTH, net.minecraft.world.level.block.state.properties.DoorHingeSide.RIGHT, true, doorTopVariant(baseDoor, "_top_cap_right_open", VariantProperties.Rotation.R180)) | ||
| .select(Direction.SOUTH, net.minecraft.world.level.block.state.properties.DoorHingeSide.LEFT, false, doorTopVariant(baseDoor, "_top_cap_left", VariantProperties.Rotation.R90)) | ||
| .select(Direction.SOUTH, net.minecraft.world.level.block.state.properties.DoorHingeSide.LEFT, true, doorTopVariant(baseDoor, "_top_cap_left_open", VariantProperties.Rotation.R180)) | ||
| .select(Direction.SOUTH, net.minecraft.world.level.block.state.properties.DoorHingeSide.RIGHT, false, doorTopVariant(baseDoor, "_top_cap_right", VariantProperties.Rotation.R90)) | ||
| .select(Direction.SOUTH, net.minecraft.world.level.block.state.properties.DoorHingeSide.RIGHT, true, doorTopVariant(baseDoor, "_top_cap_right_open", VariantProperties.Rotation.R0)) | ||
| .select(Direction.WEST, net.minecraft.world.level.block.state.properties.DoorHingeSide.LEFT, false, doorTopVariant(baseDoor, "_top_cap_left", VariantProperties.Rotation.R180)) | ||
| .select(Direction.WEST, net.minecraft.world.level.block.state.properties.DoorHingeSide.LEFT, true, doorTopVariant(baseDoor, "_top_cap_left_open", VariantProperties.Rotation.R270)) | ||
| .select(Direction.WEST, net.minecraft.world.level.block.state.properties.DoorHingeSide.RIGHT, false, doorTopVariant(baseDoor, "_top_cap_right", VariantProperties.Rotation.R180)) | ||
| .select(Direction.WEST, net.minecraft.world.level.block.state.properties.DoorHingeSide.RIGHT, true, doorTopVariant(baseDoor, "_top_cap_right_open", VariantProperties.Rotation.R90)) | ||
| )); | ||
| } | ||
|
|
||
| private static Variant doorTopVariant(Block baseDoor, String suffix, VariantProperties.Rotation rotation) { | ||
| Variant variant = Variant.variant().with(VariantProperties.MODEL, ModelLocationUtils.getModelLocation(baseDoor, suffix)); | ||
| return rotation == VariantProperties.Rotation.R0 ? variant : variant.with(VariantProperties.Y_ROT, rotation); | ||
| } |
There was a problem hiding this comment.
You should add the following import at the top.
import net.minecraft.world.level.block.state.properties.DoorHingeSide;
Also, the files meteoric_iron_door_top_cap_left.json, meteoric_iron_door_top_cap_left_open.json, meteoric_iron_door_top_cap_right.json and meteoric_iron_door_top_cap_right_open.json can be data generated.
private void createTallDoorTop(BlockModelGenerators generator, Block topBlock, Block baseDoor) {
ResourceLocation resourceLocation = ModelLocationUtils.getModelLocation(baseDoor, "_top_cap");
TextureMapping textureMapping = TextureMapping.door(resourceLocation, resourceLocation);
ResourceLocation topLeft = ModelTemplates.DOOR_TOP_LEFT.create(resourceLocation.withSuffix("_left"), textureMapping, generator.modelOutput);
ResourceLocation topLeftOpen = ModelTemplates.DOOR_TOP_LEFT_OPEN.create(resourceLocation.withSuffix("_left_open"), textureMapping, generator.modelOutput);
ResourceLocation topRight = ModelTemplates.DOOR_TOP_RIGHT.create(resourceLocation.withSuffix("_right"), textureMapping, generator.modelOutput);
ResourceLocation topRightOpen = ModelTemplates.DOOR_TOP_RIGHT_OPEN.create(resourceLocation.withSuffix("_right_open"), textureMapping, generator.modelOutput);
generator.blockStateOutput.accept(MultiVariantGenerator.multiVariant(topBlock).with(PropertyDispatch.properties(MeteoricIronDoorTopBlock.FACING, MeteoricIronDoorTopBlock.HINGE, MeteoricIronDoorTopBlock.OPEN)
.select(Direction.EAST, DoorHingeSide.LEFT, false, doorTopVariant(baseDoor, topLeft, VariantProperties.Rotation.R0))
.select(Direction.EAST, DoorHingeSide.LEFT, true, doorTopVariant(baseDoor, topLeftOpen, VariantProperties.Rotation.R90))
.select(Direction.EAST, DoorHingeSide.RIGHT, false, doorTopVariant(baseDoor, topRight, VariantProperties.Rotation.R0))
.select(Direction.EAST, DoorHingeSide.RIGHT, true, doorTopVariant(baseDoor, topRightOpen, VariantProperties.Rotation.R270))
.select(Direction.NORTH, DoorHingeSide.LEFT, false, doorTopVariant(baseDoor, topLeft, VariantProperties.Rotation.R270))
.select(Direction.NORTH, DoorHingeSide.LEFT, true, doorTopVariant(baseDoor, topLeftOpen, VariantProperties.Rotation.R0))
.select(Direction.NORTH, DoorHingeSide.RIGHT, false, doorTopVariant(baseDoor, topRight, VariantProperties.Rotation.R270))
.select(Direction.NORTH, DoorHingeSide.RIGHT, true, doorTopVariant(baseDoor, topRightOpen, VariantProperties.Rotation.R180))
.select(Direction.SOUTH, DoorHingeSide.LEFT, false, doorTopVariant(baseDoor, topLeft, VariantProperties.Rotation.R90))
.select(Direction.SOUTH, DoorHingeSide.LEFT, true, doorTopVariant(baseDoor, topLeftOpen, VariantProperties.Rotation.R180))
.select(Direction.SOUTH, DoorHingeSide.RIGHT, false, doorTopVariant(baseDoor, topRight, VariantProperties.Rotation.R90))
.select(Direction.SOUTH, DoorHingeSide.RIGHT, true, doorTopVariant(baseDoor, topRightOpen, VariantProperties.Rotation.R0))
.select(Direction.WEST, DoorHingeSide.LEFT, false, doorTopVariant(baseDoor, topLeft, VariantProperties.Rotation.R180))
.select(Direction.WEST, DoorHingeSide.LEFT, true, doorTopVariant(baseDoor, topLeftOpen, VariantProperties.Rotation.R270))
.select(Direction.WEST, DoorHingeSide.RIGHT, false, doorTopVariant(baseDoor, topRight, VariantProperties.Rotation.R180))
.select(Direction.WEST, DoorHingeSide.RIGHT, true, doorTopVariant(baseDoor, topRightOpen, VariantProperties.Rotation.R90))
));
}
private static Variant doorTopVariant(Block baseDoor, ResourceLocation resourceLocation, VariantProperties.Rotation rotation) {
Variant variant = Variant.variant().with(VariantProperties.MODEL, resourceLocation);
return rotation == VariantProperties.Rotation.R0 ? variant : variant.with(VariantProperties.Y_ROT, rotation);
}There was a problem hiding this comment.
The files src/main/resources/assets/galacticraft/blockstates/lunar_cheese_press.json, src/main/resources/assets/galacticraft/blockstates/lunar_cheese_press_part.json and src/main/resources/assets/galacticraft/models/item/lunar_cheese_press.json can be data generated fairly easily.
I would rename the createRotatedDelegate method in GCModelProviders to createRandomlyRotatedDelegate (to avoid confusion) and then add a similar method called createHorizontallyRotatedDelegate that you should call twice, once for GCBlocks.LUNAR_CHEESE_PRESS and once for GCBlocks.LUNAR_CHEESE_PRESS_PART.
private static void createHorizontallyRotatedDelegate(BlockModelGenerators generator, Block block) {
generator.blockStateOutput.accept(MultiVariantGenerator.multiVariant(block, Variant.variant().with(VariantProperties.MODEL, ModelLocationUtils.getModelLocation(block))).with(generator.createHorizontalFacingDispatch()));
}| protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, net.minecraft.world.level.LevelAccessor level, BlockPos pos, BlockPos neighborPos) { | ||
| if (direction == Direction.UP && !neighborState.is(GCBlocks.LUNAR_CHEESE_PRESS_PART)) { | ||
| return net.minecraft.world.level.block.Blocks.AIR.defaultBlockState(); |
There was a problem hiding this comment.
Please import net.minecraft.world.level.LevelAccessor and net.minecraft.world.level.block.Blocks
| protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, net.minecraft.world.level.LevelAccessor level, BlockPos pos, BlockPos neighborPos) { | ||
| if (direction == Direction.DOWN && !neighborState.is(GCBlocks.LUNAR_CHEESE_PRESS)) { | ||
| return net.minecraft.world.level.block.Blocks.AIR.defaultBlockState(); |
There was a problem hiding this comment.
Please import net.minecraft.world.level.LevelAccessor and net.minecraft.world.level.block.Blocks
There was a problem hiding this comment.
The item only seems to drop when breaking the top part of the door, or when breaking the block underneath.
Summary
This PR evolves Moon highlands villages from simple structure generation into a fully integrated gameplay system.
It introduces custom Moon villagers, a dedicated village ecosystem (population, protection, and behavior), new professions and trades, supporting POIs/workstations, and a comprehensive refresh of village world generation. The result is a more complete, self-contained settlement experience with progression and interaction systems.
Key Features
Moon Villager System
MoonVillagerEntitywith Moon-specific AI and persistence.Professions & Economy
Village Progression
Village Systems
Population & Spawning
Protection Mechanics
Golem Behavior
Content & Assets
Adds new Moon village-related blocks, items, and villager workbenches:
Also includes:
World Generation
Notes
Credit to SpatialX for all buildings and a few really good ideas