Skip to content

Commit

Permalink
Fixed zap apple trees not progressing through their stages properly
Browse files Browse the repository at this point in the history
  • Loading branch information
Sollace committed Feb 1, 2024
1 parent b194f72 commit fbe859d
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import net.minecraft.util.math.random.Random;
import net.minecraft.world.*;

public class BaseZapAppleLeavesBlock extends LeavesBlock implements TintedBlock {
public class BaseZapAppleLeavesBlock extends LeavesBlock implements TintedBlock, ZapStagedBlock {

BaseZapAppleLeavesBlock() {
super(Settings.create()
Expand All @@ -29,61 +29,35 @@ public class BaseZapAppleLeavesBlock extends LeavesBlock implements TintedBlock
}

@Override
public boolean hasRandomTicks(BlockState state) {
return !state.get(PERSISTENT);
}

@Override
public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
super.randomTick(state, world, pos, random);
tryAdvanceStage(state, world, pos, random);
}

@Override
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
if (state.get(PERSISTENT)) {
return state;
}

if (world instanceof ServerWorld sw) {
ZapAppleStageStore store = ZapAppleStageStore.get(sw);
ZapAppleStageStore.Stage currentStage = store.getStage();
if (currentStage == ZapAppleStageStore.Stage.HIBERNATING) {
return currentStage.getNewState(state);
}
public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState oldState, boolean notify) {
if (state.get(PERSISTENT)
|| oldState.isOf(state.getBlock())
|| oldState.isOf(UBlocks.ZAP_LEAVES)
|| oldState.isOf(UBlocks.FLOWERING_ZAP_LEAVES)
|| oldState.isOf(UBlocks.ZAP_LEAVES_PLACEHOLDER)
|| !(world instanceof ServerWorld sw)) {
return;
}

return state;
updateStage(state, sw, pos);
}

@Override
public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
super.scheduledTick(state, world, pos, random);
tryAdvanceStage(state, world, pos, random);
if (!state.get(PERSISTENT)) {
world.scheduleBlockTick(pos, this, 1);
}
}

private void tryAdvanceStage(BlockState state, ServerWorld world, BlockPos pos, Random random) {
if (state.get(PERSISTENT)) {
return;
}

ZapAppleStageStore store = ZapAppleStageStore.get(world);
ZapAppleStageStore.Stage newStage = store.getStage();
if (!world.isDay() && getStage(state).mustChangeIntoInstantly(newStage)) {
world.setBlockState(pos, newStage.getNewState(state));
onStageChanged(store, newStage, world, state, pos, random);
}
tryAdvanceStage(state, world, pos, random);
}

protected ZapAppleStageStore.Stage getStage(BlockState state) {
@Override
public ZapAppleStageStore.Stage getStage(BlockState state) {
return ZapAppleStageStore.Stage.FLOWERING;
}

@Override
protected boolean shouldDecay(BlockState state) {
protected final boolean shouldDecay(BlockState state) {
return false;
}

Expand Down Expand Up @@ -114,40 +88,10 @@ public void onBlockBreakStart(BlockState state, World world, BlockPos pos, Playe

@Override
public int getTint(BlockState state, @Nullable BlockRenderView world, @Nullable BlockPos pos, int foliageColor) {

if (pos == null) {
return 0x4C7EFA;
}

return TintedBlock.blend(TintedBlock.rotate(foliageColor, 2), 0x0000FF, 0.3F);
}

static void onStageChanged(ZapAppleStageStore store, ZapAppleStageStore.Stage stage, ServerWorld world, BlockState state, BlockPos pos, Random random) {
boolean mustFruit = Random.create(state.getRenderingSeed(pos)).nextInt(5) < 2;
BlockState below = world.getBlockState(pos.down());

if (world.isAir(pos.down())) {
if (stage == ZapAppleStageStore.Stage.FRUITING && mustFruit) {
world.setBlockState(pos.down(), UBlocks.ZAP_BULB.getDefaultState(), Block.NOTIFY_ALL);
store.triggerLightningStrike(pos);
}
}

if (stage != ZapAppleStageStore.Stage.HIBERNATING && world.getRandom().nextInt(10) == 0) {
store.triggerLightningStrike(pos);
}

if (stage == ZapAppleStageStore.Stage.RIPE) {
if (below.isOf(UBlocks.ZAP_BULB)) {
world.setBlockState(pos.down(), UBlocks.ZAP_APPLE.getDefaultState(), Block.NOTIFY_ALL);
store.playMoonEffect(pos);
}
}

if (mustFruit && stage == ZapAppleStageStore.Stage.HIBERNATING) {
if (below.isOf(UBlocks.ZAP_APPLE) || below.isOf(UBlocks.ZAP_BULB)) {
world.setBlockState(pos.down(), Blocks.AIR.getDefaultState());
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@

import net.minecraft.block.*;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

public class ZapAppleLeavesBlock extends BaseZapAppleLeavesBlock {
public static final EnumProperty<ZapAppleStageStore.Stage> STAGE = EnumProperty.of("stage", ZapAppleStageStore.Stage.class);
Expand All @@ -17,31 +14,13 @@ public class ZapAppleLeavesBlock extends BaseZapAppleLeavesBlock {
setDefaultState(getDefaultState().with(STAGE, ZapAppleStageStore.Stage.GREENING));
}

@Override
public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState oldState, boolean notify) {
if (state.get(PERSISTENT)
|| oldState.isOf(state.getBlock())
|| oldState.isOf(UBlocks.ZAP_LEAVES)
|| oldState.isOf(UBlocks.FLOWERING_ZAP_LEAVES)
|| oldState.isOf(UBlocks.ZAP_LEAVES_PLACEHOLDER)
|| !(world instanceof ServerWorld sw)) {
return;
}

ZapAppleStageStore store = ZapAppleStageStore.get(sw);
ZapAppleStageStore.Stage currentStage = store.getStage();
if (currentStage != getStage(state)) {
world.setBlockState(pos, currentStage.getNewState(state));
}
}

@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return super.getPlacementState(ctx).with(STAGE, ZapAppleStageStore.Stage.GREENING);
}

@Override
protected ZapAppleStageStore.Stage getStage(BlockState state) {
public ZapAppleStageStore.Stage getStage(BlockState state) {
return state.get(STAGE);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,51 +1,36 @@
package com.minelittlepony.unicopia.block;

import com.minelittlepony.unicopia.server.world.ZapAppleStageStore;
import com.minelittlepony.unicopia.server.world.ZapAppleStageStore.Stage;

import net.minecraft.block.*;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.*;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.World;

public class ZapAppleLeavesPlaceholderBlock extends AirBlock {
public class ZapAppleLeavesPlaceholderBlock extends AirBlock implements ZapStagedBlock {

ZapAppleLeavesPlaceholderBlock() {
super(Settings.create().replaceable().noCollision().dropsNothing().air());
}

@Override
public boolean hasRandomTicks(BlockState state) {
return true;
public Stage getStage(BlockState state) {
return ZapAppleStageStore.Stage.HIBERNATING;
}

@Override
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {

public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState oldState, boolean notify) {
if (world instanceof ServerWorld sw) {
ZapAppleStageStore store = ZapAppleStageStore.get(sw);
ZapAppleStageStore.Stage currentStage = store.getStage();
if (currentStage != ZapAppleStageStore.Stage.HIBERNATING) {
return currentStage.getNewState(state);
}
updateStage(state, sw, pos);
}

return state;
}

@Deprecated
@Override
public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
super.scheduledTick(state, world, pos, random);

ZapAppleStageStore store = ZapAppleStageStore.get(world);
ZapAppleStageStore.Stage newStage = store.getStage();
if (!world.isDay() && ZapAppleStageStore.Stage.HIBERNATING.mustChangeIntoInstantly(newStage)) {
state = newStage.getNewState(state);
world.setBlockState(pos, state);
BaseZapAppleLeavesBlock.onStageChanged(store, newStage, world, state, pos, random);
}

world.scheduleBlockTick(pos, state.getBlock(), 1);
tryAdvanceStage(state, world, pos, random);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.minelittlepony.unicopia.block;

import com.minelittlepony.unicopia.server.world.ZapAppleStageStore;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.random.Random;

public interface ZapStagedBlock {
ZapAppleStageStore.Stage getStage(BlockState state);

default void updateStage(BlockState state, ServerWorld world, BlockPos pos) {
ZapAppleStageStore.Stage currentStage = ZapAppleStageStore.get(world).getStage();
if (currentStage != getStage(state)) {
state = currentStage.getNewState(state);
world.setBlockState(pos, state);
}
world.scheduleBlockTick(pos, state.getBlock(), 1);
}

default void tryAdvanceStage(BlockState state, ServerWorld world, BlockPos pos, Random random) {
ZapAppleStageStore store = ZapAppleStageStore.get(world);
ZapAppleStageStore.Stage newStage = store.getStage();
if (!world.isDay() && getStage(state).mustChangeIntoInstantly(newStage)) {
state = newStage.getNewState(state);
world.setBlockState(pos, state);
onStageChanged(store, newStage, world, state, pos, random);
}
world.scheduleBlockTick(pos, state.getBlock(), 1);
}

private static void onStageChanged(ZapAppleStageStore store, ZapAppleStageStore.Stage stage, ServerWorld world, BlockState state, BlockPos pos, Random random) {
boolean mustFruit = Random.create(state.getRenderingSeed(pos)).nextInt(5) < 2;
BlockState below = world.getBlockState(pos.down());

if (world.isAir(pos.down())) {
if (stage == ZapAppleStageStore.Stage.FRUITING && mustFruit) {
world.setBlockState(pos.down(), UBlocks.ZAP_BULB.getDefaultState(), Block.NOTIFY_ALL);
store.triggerLightningStrike(pos);
}
}

if (stage != ZapAppleStageStore.Stage.HIBERNATING && world.getRandom().nextInt(10) == 0) {
store.triggerLightningStrike(pos);
}

if (stage == ZapAppleStageStore.Stage.RIPE) {
if (below.isOf(UBlocks.ZAP_BULB)) {
world.setBlockState(pos.down(), UBlocks.ZAP_APPLE.getDefaultState(), Block.NOTIFY_ALL);
store.playMoonEffect(pos);
}
}

if (mustFruit && stage == ZapAppleStageStore.Stage.HIBERNATING) {
if (below.isOf(UBlocks.ZAP_APPLE) || below.isOf(UBlocks.ZAP_BULB)) {
world.setBlockState(pos.down(), Blocks.AIR.getDefaultState());
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,8 @@ public static Stage byId(int id) {
return VALUES[MathHelper.clamp(id, 0, VALUES.length)];
}

public boolean mustChangeInto(Stage to) {
return this != to && (getNext() == to || this == HIBERNATING || to == HIBERNATING);
}

public boolean mustChangeIntoInstantly(Stage to) {
return this != to && (this == HIBERNATING || to == HIBERNATING);
return this != to;// && (this == HIBERNATING || to == HIBERNATING);
}

public BlockState getNewState(BlockState currentState) {
Expand Down

0 comments on commit fbe859d

Please sign in to comment.