Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

电灯催熟作物 #869

Merged
merged 12 commits into from
Jun 22, 2024
115 changes: 115 additions & 0 deletions common/src/main/java/dev/dubhe/anvilcraft/api/BonemealManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package dev.dubhe.anvilcraft.api;

import dev.dubhe.anvilcraft.AnvilCraft;
import dev.dubhe.anvilcraft.block.InductionLightBlock;
import dev.dubhe.anvilcraft.block.state.LightColor;
import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Tuple;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.block.BonemealableBlock;
import net.minecraft.world.level.block.GrassBlock;
import net.minecraft.world.level.block.NyliumBlock;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.NotNull;

import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;


public class BonemealManager {
private static int cooldown = 0;
private static final Set<Tuple<BlockPos, Level>> lightBlocks = Collections.synchronizedSet(new HashSet<>());

private static boolean isLighting(@NotNull BlockState state) {
return !(state.getValue(InductionLightBlock.POWERED)
|| state.getValue(InductionLightBlock.OVERLOAD));
}

private static boolean canCropGrow(@NotNull BlockState state) {
return state.getValue(InductionLightBlock.COLOR).equals(LightColor.PINK);
}

private static boolean isInSet(HashSet<Tuple<BlockPos, Level>> set, Tuple<BlockPos, Level> item) {
for (Tuple<BlockPos, Level> cur : set) {
if (cur.getA().getX() == item.getA().getX()
&& cur.getA().getY() == item.getA().getY()
&& cur.getA().getZ() == item.getA().getZ()
&& cur.getB().dimension() == item.getB().dimension()) {
return true;
}
}
return false;
}

private static HashSet<Tuple<BlockPos, Level>> doRipen(
@NotNull Level level, @NotNull BlockPos pos, @NotNull HashSet<Tuple<BlockPos, Level>> set) {
int rangeSize = AnvilCraft.config.inductionLightBlockRipeningRange;
HashSet<Tuple<BlockPos, Level>> ripened = new HashSet<>();
for (int i = -rangeSize / 2; i <= rangeSize / 2; i++) {
for (int j = -rangeSize / 2; j <= rangeSize / 2; j++) {
for (int k = -rangeSize / 2; k <= rangeSize / 2; k++) {
BlockPos pos1 = pos.offset(i, j, k);
BlockState state = level.getBlockState(pos1);
if (state.getBlock() instanceof BonemealableBlock growable
&& !growable.getClass().equals(GrassBlock.class)
&& !growable.getClass().equals(NyliumBlock.class)
&& !isInSet(set, new Tuple<>(pos1, level))
&& growable.isValidBonemealTarget(level, pos1, state, false)
&& level.getBrightness(LightLayer.BLOCK, pos1) >= 10
) {
growable.performBonemeal(
(ServerLevel) level,
level.getRandom(), pos1, state);
level.addParticle(
ParticleTypes.HAPPY_VILLAGER,
pos1.getX() + 0.5,
pos1.getY() + 0.5,
pos1.getZ() + 0.5,
0.0, 0.0, 0.0);
ripened.add(new Tuple<>(pos1, level));
}
}
}
}
return ripened;
}

/**
*
*/
public static void tick() {
cooldown--;

if (cooldown <= 0 && !lightBlocks.isEmpty()) {
cooldown = AnvilCraft.config.inductionLightBlockRipeningCooldown;
HashSet<Tuple<BlockPos, Level>> ripenedBlocks = new HashSet<>();
Iterator<Tuple<BlockPos, Level>> it = lightBlocks.iterator();
while (it.hasNext()) {
Tuple<BlockPos, Level> lightBlock = it.next();
BlockState lightBlockState = lightBlock.getB().getBlockState(lightBlock.getA());
if (lightBlockState.getBlock() instanceof InductionLightBlock) {
if (isLighting(lightBlockState) && canCropGrow(lightBlockState)) {
HashSet<Tuple<BlockPos, Level>> newRipened =
doRipen(lightBlock.getB(), lightBlock.getA(), ripenedBlocks);
ripenedBlocks.addAll(newRipened);
}
} else {
it.remove();
}
}
}

}

/**
*
*/
public static void addLightBlock(BlockPos pos, Level level) {
lightBlocks.add(new Tuple<>(pos, level));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@
import dev.dubhe.anvilcraft.block.entity.InductionLightBlockEntity;
import dev.dubhe.anvilcraft.init.ModBlockEntities;
import dev.dubhe.anvilcraft.init.ModBlocks;
import dev.dubhe.anvilcraft.init.ModItems;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.ItemTags;
import net.minecraft.util.RandomSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BaseEntityBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
Expand All @@ -35,6 +39,7 @@
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import dev.dubhe.anvilcraft.block.state.LightColor;

import javax.annotation.Nonnull;

Expand All @@ -44,10 +49,13 @@ public class InductionLightBlock extends BaseEntityBlock implements IHammerRemov
public static final VoxelShape SHAPE_Y = Block.box(6, 0, 6, 10, 16, 10);
public static final VoxelShape SHAPE_Z = Block.box(6, 6, 0, 10, 10, 16);



public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
public static final BooleanProperty OVERLOAD = IPowerComponent.OVERLOAD;
public static final EnumProperty<Direction.Axis> AXIS = BlockStateProperties.AXIS;
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
public static final EnumProperty<LightColor> COLOR = EnumProperty.create("color", LightColor.class);

/**
*
Expand All @@ -59,6 +67,7 @@ public InductionLightBlock(Properties properties) {
.setValue(OVERLOAD, true)
.setValue(AXIS, Direction.Axis.Y)
.setValue(WATERLOGGED, false)
.setValue(COLOR, LightColor.PRIMARY)
);
}

Expand All @@ -68,7 +77,8 @@ public InductionLightBlock(Properties properties) {
}

@Override
public VoxelShape getShape(
@SuppressWarnings("deprecation")
public @NotNull VoxelShape getShape(
@NotNull BlockState state,
@NotNull BlockGetter level,
@NotNull BlockPos pos,
Expand Down Expand Up @@ -97,7 +107,8 @@ public BlockState getStateForPlacement(@NotNull BlockPlaceContext context) {
.setValue(
WATERLOGGED,
context.getLevel().getFluidState(context.getClickedPos()).getType() == Fluids.WATER
);
)
.setValue(COLOR, LightColor.PRIMARY);
}

@Nullable
Expand All @@ -107,18 +118,20 @@ public BlockEntity newBlockEntity(@NotNull BlockPos pos, @NotNull BlockState sta
}

@Override
public FluidState getFluidState(BlockState state) {
@SuppressWarnings("deprecation")
public @NotNull FluidState getFluidState(BlockState state) {
return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state);
}

@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(POWERED).add(OVERLOAD).add(AXIS).add(WATERLOGGED);
builder.add(POWERED).add(OVERLOAD).add(AXIS).add(WATERLOGGED).add(COLOR);
}



@Override
@SuppressWarnings("deprecation")
public @NotNull InteractionResult use(
@NotNull BlockState state,
@NotNull Level level,
Expand All @@ -127,7 +140,9 @@ protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockSt
@NotNull InteractionHand hand,
@NotNull BlockHitResult hit
) {
return BlockPlaceAssist.tryPlace(
ItemStack itemInHand = player.getItemInHand(hand);
if (itemInHand.is(ModBlocks.INDUCTION_LIGHT.asItem())) {
InteractionResult tried = BlockPlaceAssist.tryPlace(
state,
level,
pos,
Expand All @@ -136,8 +151,25 @@ protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockSt
hit,
ModBlocks.INDUCTION_LIGHT.asItem(),
AXIS,
ModBlocks.INDUCTION_LIGHT.getDefaultState()
);
ModBlocks.INDUCTION_LIGHT.getDefaultState());

tried.shouldAwardStats();

return tried;
} else if (itemInHand.is(Items.REDSTONE)) {
level.setBlockAndUpdate(pos, state.setValue(COLOR, LightColor.PINK));
return InteractionResult.SUCCESS;
} else if (itemInHand.is(Items.GLOWSTONE_DUST)) {
level.setBlockAndUpdate(pos, state.setValue(COLOR, LightColor.YELLOW));
return InteractionResult.SUCCESS;
} else if (itemInHand.is(ItemTags.AXES)) {
level.setBlockAndUpdate(pos, state.setValue(COLOR, LightColor.PRIMARY));
itemInHand.hurtAndBreak(1, player, item -> item.broadcastBreakEvent(hand));
return InteractionResult.CONSUME_PARTIAL;
} else if (itemInHand.is(ModItems.VOID_MATTER.asItem())) {
level.setBlockAndUpdate(pos, state.setValue(COLOR, LightColor.DARK));
}
return InteractionResult.PASS;
}

@Nullable
Expand Down Expand Up @@ -180,4 +212,5 @@ public void tick(
level.setBlock(pos, state.cycle(POWERED), 2);
}
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.dubhe.anvilcraft.block.entity;

import dev.dubhe.anvilcraft.api.BonemealManager;
import dev.dubhe.anvilcraft.api.power.IPowerConsumer;
import dev.dubhe.anvilcraft.api.power.PowerGrid;
import dev.dubhe.anvilcraft.block.InductionLightBlock;
Expand All @@ -18,6 +19,9 @@ public class InductionLightBlockEntity extends BlockEntity implements IPowerCons

private PowerGrid grid;

private int rangeSize = 5;
private boolean registered = false;

public InductionLightBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState blockState) {
super(type, pos, blockState);
}
Expand All @@ -30,12 +34,18 @@ public static InductionLightBlockEntity createBlockEntity(

public void tick(Level level1) {
flushState(level1, getBlockPos());
if (!registered) {
registered = true;
BonemealManager.addLightBlock(getPos(), level);
}
}

@Override
public int getInputPower() {
if (level == null) return 1;
return getBlockState().getValue(InductionLightBlock.POWERED) ? 0 : 1;
return getBlockState()
.getValue(InductionLightBlock.POWERED)
? 0 : getBlockState().getValue(InductionLightBlock.COLOR).dissipation;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package dev.dubhe.anvilcraft.block.state;

import net.minecraft.util.StringRepresentable;
import org.jetbrains.annotations.NotNull;

public enum LightColor implements StringRepresentable {
PRIMARY("primary", 1),
PINK("pink", 16),
DARK("dark", 16),
YELLOW("yellow", 16)
;

public final String name;
public final int dissipation;

LightColor(String name, int dissipation) {
this.name = name;
this.dissipation = dissipation;
}

@Override
public @NotNull String getSerializedName() {
return this.name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ public class AnvilCraftConfig implements ConfigData {
@ConfigEntry.Gui.Tooltip()
public boolean isLaserDoImpactChecking = true;

@ConfigEntry.Gui.Tooltip
public int inductionLightBlockRipeningCooldown = 400;

@ConfigEntry.Gui.Tooltip
@ConfigEntry.BoundedDiscrete(min = 0, max = 100)
public int inductionLightBlockRipeningRange = 5;

public static class PowerConverter implements ConfigData {
@Comment("The working interval of power converters")
@ConfigEntry.Gui.Tooltip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@
"text.autoconfig.anvilcraft.option.geodeInterval.@Tooltip": "ǝpoǝb ǝɥʇ ɟo ןɐʌɹǝʇuı ɥɔɹɐǝs ǝɥ⟘",
"text.autoconfig.anvilcraft.option.geodeRadius": "snıpɐᴚ ɥɔɹɐǝS ɯnɯıxɐW ǝpoǝ⅁",
"text.autoconfig.anvilcraft.option.geodeRadius.@Tooltip": "ǝpoǝb ǝɥʇ ɟo snıpɐɹ ɥɔɹɐǝs ɯnɯıxɐɯ ǝɥ⟘",
"text.autoconfig.anvilcraft.option.inductionLightBlockRipeningCooldown": "uʍopןooƆ buıuǝdıᴚ ʞɔoןᗺ ʇɥbıꞀ uoıʇɔnpuI",
"text.autoconfig.anvilcraft.option.inductionLightBlockRipeningRange": "ǝbuɐᴚ buıuǝdıᴚ ʞɔoןᗺ ʇɥbıꞀ uoıʇɔnpuI",
"text.autoconfig.anvilcraft.option.isLaserDoImpactChecking": "buıʞɔǝɥƆ ʇɔɐdɯI oᗡ ɹǝsɐꞀ sI",
"text.autoconfig.anvilcraft.option.lightningStrikeDepth": "ɥʇdǝᗡ ǝʞıɹʇS buıuʇɥbıꞀ",
"text.autoconfig.anvilcraft.option.lightningStrikeDepth.@Tooltip": "ɥɔɐǝɹ uɐɔ ǝʞıɹʇs buıuʇɥbıן ɐ ɥʇdǝp ɯnɯıxɐW",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@
"text.autoconfig.anvilcraft.option.geodeInterval.@Tooltip": "The search interval of the geode",
"text.autoconfig.anvilcraft.option.geodeRadius": "Geode Maximum Search Radius",
"text.autoconfig.anvilcraft.option.geodeRadius.@Tooltip": "The maximum search radius of the geode",
"text.autoconfig.anvilcraft.option.inductionLightBlockRipeningCooldown": "Induction Light Block Ripening Cooldown",
"text.autoconfig.anvilcraft.option.inductionLightBlockRipeningRange": "Induction Light Block Ripening Range",
"text.autoconfig.anvilcraft.option.isLaserDoImpactChecking": "Is Laser Do Impact Checking",
"text.autoconfig.anvilcraft.option.lightningStrikeDepth": "Lightning Strike Depth",
"text.autoconfig.anvilcraft.option.lightningStrikeDepth.@Tooltip": "Maximum depth a lightning strike can reach",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.dubhe.anvilcraft.event.fabric;

import dev.dubhe.anvilcraft.AnvilCraft;
import dev.dubhe.anvilcraft.api.BonemealManager;
import dev.dubhe.anvilcraft.api.chargecollector.ThermoManager;
import dev.dubhe.anvilcraft.api.event.server.ServerEndDataPackReloadEvent;
import dev.dubhe.anvilcraft.api.event.server.ServerStartedEvent;
Expand Down Expand Up @@ -38,6 +39,7 @@ private static void endDataPackReload(
private static void startTick(MinecraftServer server) {
PowerGrid.tickGrid();
ThermoManager.tick();
BonemealManager.tick();
RandomChuckTickLoadManager.tick();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@
"text.autoconfig.anvilcraft.option.geodeInterval.@Tooltip": "ǝpoǝb ǝɥʇ ɟo ןɐʌɹǝʇuı ɥɔɹɐǝs ǝɥ⟘",
"text.autoconfig.anvilcraft.option.geodeRadius": "snıpɐᴚ ɥɔɹɐǝS ɯnɯıxɐW ǝpoǝ⅁",
"text.autoconfig.anvilcraft.option.geodeRadius.@Tooltip": "ǝpoǝb ǝɥʇ ɟo snıpɐɹ ɥɔɹɐǝs ɯnɯıxɐɯ ǝɥ⟘",
"text.autoconfig.anvilcraft.option.inductionLightBlockRipeningCooldown": "uʍopןooƆ buıuǝdıᴚ ʞɔoןᗺ ʇɥbıꞀ uoıʇɔnpuI",
"text.autoconfig.anvilcraft.option.inductionLightBlockRipeningRange": "ǝbuɐᴚ buıuǝdıᴚ ʞɔoןᗺ ʇɥbıꞀ uoıʇɔnpuI",
"text.autoconfig.anvilcraft.option.isLaserDoImpactChecking": "buıʞɔǝɥƆ ʇɔɐdɯI oᗡ ɹǝsɐꞀ sI",
"text.autoconfig.anvilcraft.option.lightningStrikeDepth": "ɥʇdǝᗡ ǝʞıɹʇS buıuʇɥbıꞀ",
"text.autoconfig.anvilcraft.option.lightningStrikeDepth.@Tooltip": "ɥɔɐǝɹ uɐɔ ǝʞıɹʇs buıuʇɥbıן ɐ ɥʇdǝp ɯnɯıxɐW",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@
"text.autoconfig.anvilcraft.option.geodeInterval.@Tooltip": "The search interval of the geode",
"text.autoconfig.anvilcraft.option.geodeRadius": "Geode Maximum Search Radius",
"text.autoconfig.anvilcraft.option.geodeRadius.@Tooltip": "The maximum search radius of the geode",
"text.autoconfig.anvilcraft.option.inductionLightBlockRipeningCooldown": "Induction Light Block Ripening Cooldown",
"text.autoconfig.anvilcraft.option.inductionLightBlockRipeningRange": "Induction Light Block Ripening Range",
"text.autoconfig.anvilcraft.option.isLaserDoImpactChecking": "Is Laser Do Impact Checking",
"text.autoconfig.anvilcraft.option.lightningStrikeDepth": "Lightning Strike Depth",
"text.autoconfig.anvilcraft.option.lightningStrikeDepth.@Tooltip": "Maximum depth a lightning strike can reach",
Expand Down
Loading
Loading