Skip to content

Commit

Permalink
添加紫水晶工作台 #1029
Browse files Browse the repository at this point in the history
  • Loading branch information
DancingSnow0517 committed Sep 30, 2024
1 parent 0e0c559 commit cef17a0
Show file tree
Hide file tree
Showing 14 changed files with 366 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/generated/resources/assets/anvilcraft/lang/en_ud.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"block.anvilcraft.crab_trap": "dɐɹ⟘ qɐɹƆ",
"block.anvilcraft.cream_block": "ʞɔoןᗺ ɯɐǝɹƆ",
"block.anvilcraft.creative_generator": "ɹoʇɐɹǝuǝ⅁ ǝʌıʇɐǝɹƆ",
"block.anvilcraft.crystal_crafting_table": "ǝןqɐ⟘ buıʇɟɐɹƆ ןɐʇsʎɹƆ",
"block.anvilcraft.cursed_gold_block": "ʞɔoןᗺ pןo⅁ pǝsɹnƆ",
"block.anvilcraft.cut_ember_metal_block": "ʞɔoןᗺ ןɐʇǝW ɹǝqɯƎ ʇnƆ",
"block.anvilcraft.cut_ember_metal_pillar": "ɹɐןןıԀ ןɐʇǝW ɹǝqɯƎ ʇnƆ",
Expand Down
1 change: 1 addition & 0 deletions src/generated/resources/assets/anvilcraft/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"block.anvilcraft.crab_trap": "Crab Trap",
"block.anvilcraft.cream_block": "Cream Block",
"block.anvilcraft.creative_generator": "Creative Generator",
"block.anvilcraft.crystal_crafting_table": "Crystal Crafting Table",
"block.anvilcraft.cursed_gold_block": "Cursed Gold Block",
"block.anvilcraft.cut_ember_metal_block": "Cut Ember Metal Block",
"block.anvilcraft.cut_ember_metal_pillar": "Cut Ember Metal Pillar",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"parent": "anvilcraft:block/crystal_crafting_table"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"parent": "minecraft:recipes/root",
"criteria": {
"has_the_recipe": {
"conditions": {
"recipe": "anvilcraft:crystal_crafting_table"
},
"trigger": "minecraft:recipe_unlocked"
},
"hasitem": {
"conditions": {
"items": [
{
"items": "minecraft:amethyst_shard"
}
]
},
"trigger": "minecraft:inventory_changed"
}
},
"requirements": [
[
"has_the_recipe",
"hasitem"
]
],
"rewards": {
"recipes": [
"anvilcraft:crystal_crafting_table"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"type": "minecraft:block",
"pools": [
{
"bonus_rolls": 0.0,
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
],
"entries": [
{
"type": "minecraft:item",
"name": "anvilcraft:crystal_crafting_table"
}
],
"rolls": 1.0
}
],
"random_sequence": "anvilcraft:blocks/crystal_crafting_table"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"type": "minecraft:crafting_shaped",
"category": "misc",
"key": {
"A": {
"item": "minecraft:amethyst_shard"
},
"B": {
"item": "minecraft:crafting_table"
}
},
"pattern": [
" A ",
"ABA",
" A "
],
"result": {
"count": 1,
"id": "anvilcraft:crystal_crafting_table"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"values": [
"anvilcraft:crystal_crafting_table"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"anvilcraft:ruby_prism",
"anvilcraft:overseer",
"anvilcraft:jewelcrafting_table",
"anvilcraft:crystal_crafting_table",
"anvilcraft:chute",
"anvilcraft:magnetic_chute",
"anvilcraft:simple_chute",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
package dev.dubhe.anvilcraft.block;

import dev.dubhe.anvilcraft.api.hammer.IHammerRemovable;
import dev.dubhe.anvilcraft.init.ModBlocks;
import dev.dubhe.anvilcraft.init.ModMenuTypes;
import dev.dubhe.anvilcraft.util.Util;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.stats.Stats;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.SimpleMenuProvider;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.ContainerLevelAccess;
import net.minecraft.world.inventory.CraftingMenu;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.TransparentBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.EnumProperty;
import net.minecraft.world.phys.BlockHitResult;

import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.List;


@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public class CrystalCraftingTableBlock extends TransparentBlock implements IHammerRemovable {

public static final EnumProperty<Type> TYPE = EnumProperty.create("type", Type.class);

public CrystalCraftingTableBlock(Properties properties) {
super(properties);
registerDefaultState(stateDefinition.any().setValue(TYPE, Type.SINGLE));
}

@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(TYPE);
}

@Override
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
if (level.isClientSide) return InteractionResult.SUCCESS;
ModMenuTypes.open((ServerPlayer) player, getMenuProvider(state, level, pos));
player.awardStat(Stats.INTERACT_WITH_CRAFTING_TABLE);
return InteractionResult.sidedSuccess(level.isClientSide());
}

@Override
protected MenuProvider getMenuProvider(BlockState state, Level level, BlockPos pos) {
return new SimpleMenuProvider(
(id, inventory, player) -> new CraftingMenu(id, inventory, ContainerLevelAccess.create(level, pos)),
Component.translatable("container.crafting")
);
}

@Override
protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) {
travelAndCheck(level, pos);
}

@Override
protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
for (Direction direction : Util.HORIZONTAL_DIRECTIONS) {
travelAndCheck(level, pos.relative(direction));
}
}


private static void travelAndCheck(Level level, BlockPos pos) {
List<BlockPos> posList = new ArrayList<>();
BlockPos.breadthFirstTraversal(
pos,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
Util::acceptHorizontalDirections,
blockPos -> {
BlockState blockState = level.getBlockState(blockPos);
if (blockState.is(ModBlocks.CRYSTAL_CRAFTING_TABLE)) {
posList.add(blockPos);
return true;
}
return false;
}
);
if (!posList.isEmpty()) {
checkPosAndUpdate(level, posList);
}
}

/**
* 检查给定坐标是否是矩形,且更新他们的方块状态
*
* @param level level
* @param posList 方块列表
*/
private static void checkPosAndUpdate(Level level, List<BlockPos> posList) {
int minX = Integer.MAX_VALUE;
int maxX = Integer.MIN_VALUE;
int minZ = Integer.MAX_VALUE;
int maxZ = Integer.MIN_VALUE;

int posY = posList.getFirst().getY();

for (BlockPos pos : posList) {
minX = Math.min(minX, pos.getX());
maxX = Math.max(maxX, pos.getX());
minZ = Math.min(minZ, pos.getZ());
maxZ = Math.max(maxZ, pos.getZ());
}

// 检查区域内是否全部为水晶工作台
boolean flag = true;
for (int x = minX; x <= maxX && flag; x++) {
for (int z = minZ; z <= maxZ && flag; z++) {
BlockPos checkPos = new BlockPos(x, posY, z);
if (!level.getBlockState(checkPos).is(ModBlocks.CRYSTAL_CRAFTING_TABLE)) {
flag = false;
}
}
}

int width = maxX - minX + 1;
int height = maxZ - minZ + 1;

if (flag && width > 1 && height > 1) {
// 修改状态
// center
for (int x = minX + 1; x <= maxX - 1; x++) {
for (int z = minZ + 1; z <= maxZ - 1; z++) {
BlockPos pos = new BlockPos(x, posY, z);
level.setBlockAndUpdate(pos, ModBlocks.CRYSTAL_CRAFTING_TABLE.getDefaultState().setValue(TYPE, Type.CENTER));
}
}

// corner
level.setBlockAndUpdate(
new BlockPos(minX, posY, minZ),
ModBlocks.CRYSTAL_CRAFTING_TABLE.getDefaultState().setValue(TYPE, Type.CORNER_NORTH_WEST)
);
level.setBlockAndUpdate(
new BlockPos(maxX, posY, minZ),
ModBlocks.CRYSTAL_CRAFTING_TABLE.getDefaultState().setValue(TYPE, Type.CORNER_NORTH_EAST)
);
level.setBlockAndUpdate(
new BlockPos(minX, posY, maxZ),
ModBlocks.CRYSTAL_CRAFTING_TABLE.getDefaultState().setValue(TYPE, Type.CORNER_SOUTH_WEST)
);
level.setBlockAndUpdate(
new BlockPos(maxX, posY, maxZ),
ModBlocks.CRYSTAL_CRAFTING_TABLE.getDefaultState().setValue(TYPE, Type.CORNER_SOUTH_EAST)
);

//side
for (int z = minZ + 1; z <= maxZ - 1; z++) {
level.setBlockAndUpdate(
new BlockPos(minX, posY, z),
ModBlocks.CRYSTAL_CRAFTING_TABLE.getDefaultState().setValue(TYPE, Type.SIDE_WEST)
);
level.setBlockAndUpdate(
new BlockPos(maxX, posY, z),
ModBlocks.CRYSTAL_CRAFTING_TABLE.getDefaultState().setValue(TYPE, Type.SIDE_EAST)
);
}
for (int x = minX + 1; x <= maxX - 1; x++) {
level.setBlockAndUpdate(
new BlockPos(x, posY, minZ),
ModBlocks.CRYSTAL_CRAFTING_TABLE.getDefaultState().setValue(TYPE, Type.SIDE_NORTH)
);
level.setBlockAndUpdate(
new BlockPos(x, posY, maxZ),
ModBlocks.CRYSTAL_CRAFTING_TABLE.getDefaultState().setValue(TYPE, Type.SIDE_SOUTH)
);
}
} else {
// 恢复无连接状态
for (BlockPos pos : posList) {
level.setBlockAndUpdate(pos, ModBlocks.CRYSTAL_CRAFTING_TABLE.getDefaultState());
}
}
}

public enum Type implements StringRepresentable {
SINGLE("single"),
CENTER("center"),
SIDE_NORTH("side_n"),
SIDE_EAST("side_e"),
SIDE_SOUTH("side_s"),
SIDE_WEST("side_w"),
CORNER_NORTH_WEST("corner_nw"),
CORNER_NORTH_EAST("corner_ne"),
CORNER_SOUTH_WEST("corner_sw"),
CORNER_SOUTH_EAST("corner_se");

final String serializedName;

Type(String serializedName) {
this.serializedName = serializedName;
}

@Override
public String getSerializedName() {
return serializedName;
}


@Override
public String toString() {
return getSerializedName();
}
}
}
24 changes: 24 additions & 0 deletions src/main/java/dev/dubhe/anvilcraft/init/ModBlocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import dev.dubhe.anvilcraft.block.CrabTrapBlock;
import dev.dubhe.anvilcraft.block.CreamBlock;
import dev.dubhe.anvilcraft.block.CreativeGeneratorBlock;
import dev.dubhe.anvilcraft.block.CrystalCraftingTableBlock;
import dev.dubhe.anvilcraft.block.DischargerBlock;
import dev.dubhe.anvilcraft.block.EmberAnvilBlock;
import dev.dubhe.anvilcraft.block.EmberGrindstone;
Expand Down Expand Up @@ -1085,6 +1086,29 @@ public class ModBlocks {
.save(provider);
})
.register();
public static final BlockEntry<CrystalCraftingTableBlock> CRYSTAL_CRAFTING_TABLE = REGISTRATE
.block("crystal_crafting_table", CrystalCraftingTableBlock::new)
.properties(properties -> properties
.mapColor(MapColor.COLOR_PURPLE)
.strength(1.5F, 3)
.sound(SoundType.AMETHYST)
.noOcclusion()
)
.blockstate((ctx, provider) -> {
})
.simpleItem()
.tag(BlockTags.MINEABLE_WITH_PICKAXE, Tags.Blocks.PLAYER_WORKSTATIONS_CRAFTING_TABLES)
.recipe((ctx, provider) -> {
ShapedRecipeBuilder.shaped(RecipeCategory.MISC, ctx.get())
.pattern(" A ")
.pattern("ABA")
.pattern(" A ")
.define('A', Items.AMETHYST_SHARD)
.define('B', Items.CRAFTING_TABLE)
.unlockedBy("hasitem", AnvilCraftDatagen.has(Items.AMETHYST_SHARD))
.save(provider);
})
.register();
public static final BlockEntry<CrabTrapBlock> CRAB_TRAP = REGISTRATE
.block("crab_trap", CrabTrapBlock::new)
.properties(p -> p.sound(SoundType.SCAFFOLDING).strength(2))
Expand Down
Loading

0 comments on commit cef17a0

Please sign in to comment.