mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-28 19:39:11 +00:00
swing hand/particles for crop
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
package net.momirealms.craftengine.bukkit.block.behavior;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.ParticleUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||
import net.momirealms.craftengine.core.block.CustomBlock;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
@@ -13,6 +15,7 @@ import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.RandomUtils;
|
||||
import net.momirealms.craftengine.core.util.Tuple;
|
||||
import net.momirealms.craftengine.shared.block.BlockBehavior;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
@@ -38,6 +41,10 @@ public class CropBlockBehavior extends BushBlockBehavior {
|
||||
return state.get(ageProperty);
|
||||
}
|
||||
|
||||
public boolean isMaxAge(ImmutableBlockState state) {
|
||||
return state.get(ageProperty) == ageProperty.max;
|
||||
}
|
||||
|
||||
private static int getRawBrightness(Object level, Object pos) throws InvocationTargetException, IllegalAccessException {
|
||||
return (int) Reflections.method$BlockAndTintGetter$getRawBrightness.invoke(level, pos, 0);
|
||||
}
|
||||
@@ -93,12 +100,31 @@ public class CropBlockBehavior extends BushBlockBehavior {
|
||||
if (immutableBlockState == null || immutableBlockState.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
boolean sendParticles = false;
|
||||
Object visualState = immutableBlockState.vanillaBlockState().handle();
|
||||
Object visualStateBlock = Reflections.method$BlockStateBase$getBlock.invoke(visualState);
|
||||
if (Reflections.clazz$BonemealableBlock.isInstance(visualStateBlock)) {
|
||||
boolean is = (boolean) Reflections.method$BonemealableBlock$isValidBonemealTarget.invoke(visualStateBlock, level, pos, visualState);
|
||||
if (!is) {
|
||||
sendParticles = true;
|
||||
}
|
||||
} else {
|
||||
sendParticles = true;
|
||||
}
|
||||
|
||||
int i = this.getAge(immutableBlockState) + RandomUtils.generateRandomInt(2, 5);
|
||||
int maxAge = this.ageProperty.max;
|
||||
if (i > maxAge) {
|
||||
i = maxAge;
|
||||
}
|
||||
Reflections.method$Level$setBlock.invoke(level, pos, immutableBlockState.with(this.ageProperty, i).customBlockState().handle(), UpdateOption.UPDATE_NONE.flags());
|
||||
if (sendParticles) {
|
||||
World world = FastNMS.INSTANCE.method$Level$getCraftWorld(level);
|
||||
int x = FastNMS.INSTANCE.field$Vec3i$x(pos);
|
||||
int y = FastNMS.INSTANCE.field$Vec3i$y(pos);
|
||||
int z = FastNMS.INSTANCE.field$Vec3i$z(pos);
|
||||
world.spawnParticle(ParticleUtils.getParticle("HAPPY_VILLAGER"), x + 0.5, y + 0.5, z + 0.5, 12, 0.2, 0.2, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Factory implements BlockBehaviorFactory {
|
||||
|
||||
@@ -3,10 +3,7 @@ package net.momirealms.craftengine.bukkit.block.behavior;
|
||||
import net.momirealms.craftengine.bukkit.api.CraftEngineBlocks;
|
||||
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.FeatureUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||
import net.momirealms.craftengine.bukkit.util.*;
|
||||
import net.momirealms.craftengine.core.block.CustomBlock;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.block.UpdateOption;
|
||||
@@ -98,8 +95,34 @@ public class SaplingBlockBehavior extends BushBlockBehavior {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBoneMealSuccess(Object thisBlock, Object[] args) {
|
||||
return RandomUtils.generateRandomDouble(0d, 1d) < this.boneMealSuccessChance;
|
||||
public boolean isBoneMealSuccess(Object thisBlock, Object[] args) throws Exception {
|
||||
boolean success = RandomUtils.generateRandomDouble(0d, 1d) < this.boneMealSuccessChance;
|
||||
Object level = args[0];
|
||||
Object blockPos = args[2];
|
||||
Object blockState = args[3];
|
||||
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
if (immutableBlockState == null || immutableBlockState.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
boolean sendParticles = false;
|
||||
Object visualState = immutableBlockState.vanillaBlockState().handle();
|
||||
Object visualStateBlock = Reflections.method$BlockStateBase$getBlock.invoke(visualState);
|
||||
if (Reflections.clazz$BonemealableBlock.isInstance(visualStateBlock)) {
|
||||
boolean is = (boolean) Reflections.method$BonemealableBlock$isValidBonemealTarget.invoke(visualStateBlock, level, blockPos, visualState);
|
||||
if (!is) {
|
||||
sendParticles = true;
|
||||
}
|
||||
} else {
|
||||
sendParticles = true;
|
||||
}
|
||||
if (sendParticles) {
|
||||
World world = FastNMS.INSTANCE.method$Level$getCraftWorld(level);
|
||||
int x = FastNMS.INSTANCE.field$Vec3i$x(blockPos);
|
||||
int y = FastNMS.INSTANCE.field$Vec3i$y(blockPos);
|
||||
int z = FastNMS.INSTANCE.field$Vec3i$z(blockPos);
|
||||
world.spawnParticle(ParticleUtils.getParticle("HAPPY_VILLAGER"), x + 0.5, y + 0.5, z + 0.5, 12, 0.2, 0.2, 0.2);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.item;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.compatibility.item.NeigeItemsProvider;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.AxeItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.BoneMealItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.BucketItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.WaterBucketItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.factory.BukkitItemFactory;
|
||||
@@ -50,6 +51,7 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
registerVanillaItemExtraBehavior(AxeItemBehavior.INSTANCE, ItemKeys.AXES);
|
||||
registerVanillaItemExtraBehavior(WaterBucketItemBehavior.INSTANCE, ItemKeys.WATER_BUCKETS);
|
||||
registerVanillaItemExtraBehavior(BucketItemBehavior.INSTANCE, ItemKeys.BUCKET);
|
||||
registerVanillaItemExtraBehavior(BoneMealItemBehavior.INSTANCE, ItemKeys.BONE_MEAL);
|
||||
}
|
||||
|
||||
private static BukkitItemManager instance;
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package net.momirealms.craftengine.bukkit.item.behavior;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
||||
import net.momirealms.craftengine.bukkit.block.behavior.CropBlockBehavior;
|
||||
import net.momirealms.craftengine.bukkit.block.behavior.SaplingBlockBehavior;
|
||||
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||
import net.momirealms.craftengine.bukkit.world.BukkitWorldBlock;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionResult;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory;
|
||||
import net.momirealms.craftengine.core.item.context.UseOnContext;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
public class BoneMealItemBehavior extends ItemBehavior {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final BoneMealItemBehavior INSTANCE = new BoneMealItemBehavior();
|
||||
|
||||
@Override
|
||||
public InteractionResult useOnBlock(UseOnContext context) {
|
||||
BukkitWorldBlock clicked = (BukkitWorldBlock) context.getLevel().getBlockAt(context.getClickedPos());
|
||||
Block block = clicked.block();
|
||||
ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockDataToId(block.getBlockData()));
|
||||
if (state == null || state.isEmpty()) return InteractionResult.PASS;
|
||||
|
||||
boolean shouldHandle =false;
|
||||
if (state.behavior() instanceof CropBlockBehavior blockBehavior) {
|
||||
if (!blockBehavior.isMaxAge(state)) {
|
||||
shouldHandle = true;
|
||||
}
|
||||
} else if (state.behavior() instanceof SaplingBlockBehavior) {
|
||||
shouldHandle = true;
|
||||
}
|
||||
|
||||
if (!shouldHandle) return InteractionResult.PASS;
|
||||
|
||||
boolean sendSwing = false;
|
||||
try {
|
||||
Object visualState = state.vanillaBlockState().handle();
|
||||
Object visualStateBlock = Reflections.method$BlockStateBase$getBlock.invoke(visualState);
|
||||
if (Reflections.clazz$BonemealableBlock.isInstance(visualStateBlock)) {
|
||||
boolean is = (boolean) Reflections.method$BonemealableBlock$isValidBonemealTarget.invoke(visualStateBlock, context.getLevel().serverWorld(), LocationUtils.toBlockPos(context.getClickedPos()), visualState);
|
||||
if (!is) {
|
||||
sendSwing = true;
|
||||
}
|
||||
} else {
|
||||
sendSwing = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Failed to check visual state bone meal state", e);
|
||||
}
|
||||
if (sendSwing) {
|
||||
context.getPlayer().swingHand(context.getHand());
|
||||
}
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
public static class Factory implements ItemBehaviorFactory {
|
||||
|
||||
@Override
|
||||
public ItemBehavior create(Pack pack, Path path, Key id, Map<String, Object> arguments) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ public class BukkitItemBehaviors extends ItemBehaviors {
|
||||
public static final Key AXE_ITEM = Key.from("craftengine:axe_item");
|
||||
public static final Key WATER_BUCKET_ITEM = Key.from("craftengine:water_bucket_item");
|
||||
public static final Key BUCKET_ITEM = Key.from("craftengine:bucket_item");
|
||||
public static final Key BONE_MEAL_ITEM = Key.from("craftengine:bone_meal_item");
|
||||
|
||||
public static void init() {
|
||||
register(EMPTY, EmptyItemBehavior.FACTORY);
|
||||
@@ -20,5 +21,6 @@ public class BukkitItemBehaviors extends ItemBehaviors {
|
||||
register(AXE_ITEM, AxeItemBehavior.FACTORY);
|
||||
register(WATER_BUCKET_ITEM, WaterBucketItemBehavior.FACTORY);
|
||||
register(BUCKET_ITEM, BucketItemBehavior.FACTORY);
|
||||
register(BONE_MEAL_ITEM, BoneMealItemBehavior.FACTORY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package net.momirealms.craftengine.bukkit.util;
|
||||
|
||||
import org.bukkit.Particle;
|
||||
|
||||
public class ParticleUtils {
|
||||
|
||||
public static Particle getParticle(String particle) {
|
||||
try {
|
||||
return Particle.valueOf(particle);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return switch (particle) {
|
||||
case "REDSTONE" -> Particle.valueOf("DUST");
|
||||
case "VILLAGER_HAPPY" -> Particle.valueOf("HAPPY_VILLAGER");
|
||||
default -> Particle.valueOf(particle);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user