mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
Merge pull request #486 from jhqwqmc/feat/drop-experience-block
添加掉落经验方块
This commit is contained in:
@@ -47,6 +47,7 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
|
|||||||
public static final Key SURFACE_SPREADING_BLOCK = Key.from("craftengine:surface_spreading_block");
|
public static final Key SURFACE_SPREADING_BLOCK = Key.from("craftengine:surface_spreading_block");
|
||||||
public static final Key SNOWY_BLOCK = Key.from("craftengine:snowy_block");
|
public static final Key SNOWY_BLOCK = Key.from("craftengine:snowy_block");
|
||||||
public static final Key HANGABLE_BLOCK = Key.from("craftengine:hangable_block");
|
public static final Key HANGABLE_BLOCK = Key.from("craftengine:hangable_block");
|
||||||
|
public static final Key DROP_EXPERIENCE_BLOCK = Key.from("craftengine:drop_experience_block");
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
register(EMPTY, (block, args) -> EmptyBlockBehavior.INSTANCE);
|
register(EMPTY, (block, args) -> EmptyBlockBehavior.INSTANCE);
|
||||||
@@ -92,5 +93,6 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
|
|||||||
register(SURFACE_SPREADING_BLOCK, SurfaceSpreadingBlockBehavior.FACTORY);
|
register(SURFACE_SPREADING_BLOCK, SurfaceSpreadingBlockBehavior.FACTORY);
|
||||||
register(SNOWY_BLOCK, SnowyBlockBehavior.FACTORY);
|
register(SNOWY_BLOCK, SnowyBlockBehavior.FACTORY);
|
||||||
register(HANGABLE_BLOCK, HangableBlockBehavior.FACTORY);
|
register(HANGABLE_BLOCK, HangableBlockBehavior.FACTORY);
|
||||||
|
register(DROP_EXPERIENCE_BLOCK, DropExperienceBlockBehavior.FACTORY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
package net.momirealms.craftengine.bukkit.block.behavior;
|
||||||
|
|
||||||
|
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
|
||||||
|
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||||
|
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||||
|
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||||
|
import net.momirealms.craftengine.bukkit.world.BukkitWorldManager;
|
||||||
|
import net.momirealms.craftengine.core.block.BlockBehavior;
|
||||||
|
import net.momirealms.craftengine.core.block.BlockSettings;
|
||||||
|
import net.momirealms.craftengine.core.block.CustomBlock;
|
||||||
|
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||||
|
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
|
||||||
|
import net.momirealms.craftengine.core.item.Item;
|
||||||
|
import net.momirealms.craftengine.core.loot.LootContext;
|
||||||
|
import net.momirealms.craftengine.core.plugin.context.Condition;
|
||||||
|
import net.momirealms.craftengine.core.plugin.context.Context;
|
||||||
|
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
|
||||||
|
import net.momirealms.craftengine.core.plugin.context.condition.AllOfCondition;
|
||||||
|
import net.momirealms.craftengine.core.plugin.context.event.EventConditions;
|
||||||
|
import net.momirealms.craftengine.core.plugin.context.number.NumberProvider;
|
||||||
|
import net.momirealms.craftengine.core.plugin.context.number.NumberProviders;
|
||||||
|
import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters;
|
||||||
|
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||||
|
import net.momirealms.craftengine.core.world.BlockPos;
|
||||||
|
import net.momirealms.craftengine.core.world.Vec3d;
|
||||||
|
import net.momirealms.craftengine.core.world.World;
|
||||||
|
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public class DropExperienceBlockBehavior extends BukkitBlockBehavior {
|
||||||
|
public static final Factory FACTORY = new Factory();
|
||||||
|
private final NumberProvider amount;
|
||||||
|
private final Condition<Context> conditions;
|
||||||
|
|
||||||
|
public DropExperienceBlockBehavior(CustomBlock customBlock, NumberProvider amount, Condition<Context> conditions) {
|
||||||
|
super(customBlock);
|
||||||
|
this.amount = amount;
|
||||||
|
this.conditions = conditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawnAfterBreak(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||||
|
boolean dropExperience = (boolean) args[4]; // 通常来说是 false
|
||||||
|
Item<ItemStack> item = BukkitItemManager.instance().wrap(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(args[3]));
|
||||||
|
if (!dropExperience) {
|
||||||
|
ImmutableBlockState state = BlockStateUtils.getOptionalCustomBlockState(args[0]).orElse(null);
|
||||||
|
if (state == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BlockSettings settings = state.settings();
|
||||||
|
if (settings.requireCorrectTool()) {
|
||||||
|
if (item.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean cannotBreak = !settings.isCorrectTool(item.id())
|
||||||
|
&& (!settings.respectToolComponent()
|
||||||
|
|| !FastNMS.INSTANCE.method$ItemStack$isCorrectToolForDrops(args[3], state.customBlockState().literalObject()));
|
||||||
|
if (cannotBreak) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
World world = BukkitWorldManager.instance().wrap(FastNMS.INSTANCE.method$Level$getCraftWorld(args[1]));
|
||||||
|
BlockPos pos = LocationUtils.fromBlockPos(args[2]);
|
||||||
|
tryDropExperience(world, pos, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tryDropExperience(World world, BlockPos pos, Item<ItemStack> item) {
|
||||||
|
Vec3d dropPos = Vec3d.atCenterOf(pos);
|
||||||
|
ContextHolder holder = ContextHolder.builder()
|
||||||
|
.withParameter(DirectContextParameters.POSITION, new WorldPosition(world, dropPos))
|
||||||
|
.withParameter(DirectContextParameters.ITEM_IN_HAND, item)
|
||||||
|
.build();
|
||||||
|
LootContext context = new LootContext(world, null, 1.0f, holder);
|
||||||
|
if (this.conditions != null && !this.conditions.test(context)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int finalAmount = this.amount.getInt(context);
|
||||||
|
if (finalAmount <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
world.dropExp(dropPos, finalAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Factory implements BlockBehaviorFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
|
||||||
|
NumberProvider amount = NumberProviders.fromObject(arguments.getOrDefault("amount", 0));
|
||||||
|
Condition<Context> conditions = null;
|
||||||
|
List<Condition<Context>> conditionList = ResourceConfigUtils.parseConfigAsList(ResourceConfigUtils.get(arguments, "conditions", "condition"), EventConditions::fromMap);
|
||||||
|
if (conditionList.size() == 1) {
|
||||||
|
conditions = conditionList.getFirst();
|
||||||
|
} else if (!conditionList.isEmpty()) {
|
||||||
|
conditions = new AllOfCondition<>(conditionList);
|
||||||
|
}
|
||||||
|
return new DropExperienceBlockBehavior(block, amount, conditions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,13 +27,17 @@ items:
|
|||||||
texture: minecraft:item/custom/topaz
|
texture: minecraft:item/custom/topaz
|
||||||
blocks:
|
blocks:
|
||||||
default:topaz_ore:
|
default:topaz_ore:
|
||||||
|
behavior:
|
||||||
|
type: drop_experience_block
|
||||||
|
amount: 3~7
|
||||||
|
condition:
|
||||||
|
type: enchantment
|
||||||
|
predicate: minecraft:silk_touch<=0
|
||||||
loot:
|
loot:
|
||||||
template: default:loot_table/ore
|
template: default:loot_table/ore
|
||||||
arguments:
|
arguments:
|
||||||
ore_drop: default:topaz
|
ore_drop: default:topaz
|
||||||
ore_block: default:topaz_ore
|
ore_block: default:topaz_ore
|
||||||
min_exp: 3
|
|
||||||
max_exp: 7
|
|
||||||
settings:
|
settings:
|
||||||
template: default:settings/ore
|
template: default:settings/ore
|
||||||
arguments:
|
arguments:
|
||||||
@@ -45,13 +49,17 @@ blocks:
|
|||||||
arguments:
|
arguments:
|
||||||
path: minecraft:block/custom/topaz_ore
|
path: minecraft:block/custom/topaz_ore
|
||||||
default:deepslate_topaz_ore:
|
default:deepslate_topaz_ore:
|
||||||
|
behavior:
|
||||||
|
type: drop_experience_block
|
||||||
|
amount: 3~7
|
||||||
|
condition:
|
||||||
|
type: enchantment
|
||||||
|
predicate: minecraft:silk_touch<=0
|
||||||
loot:
|
loot:
|
||||||
template: default:loot_table/ore
|
template: default:loot_table/ore
|
||||||
arguments:
|
arguments:
|
||||||
ore_drop: default:topaz
|
ore_drop: default:topaz
|
||||||
ore_block: default:deepslate_topaz_ore
|
ore_block: default:deepslate_topaz_ore
|
||||||
min_exp: 3
|
|
||||||
max_exp: 7
|
|
||||||
settings:
|
settings:
|
||||||
template: default:settings/deepslate_ore
|
template: default:settings/deepslate_ore
|
||||||
arguments:
|
arguments:
|
||||||
|
|||||||
@@ -180,7 +180,6 @@ templates:
|
|||||||
# ore_block: the ore block
|
# ore_block: the ore block
|
||||||
# ore_drop: the drops of the ore material
|
# ore_drop: the drops of the ore material
|
||||||
# ore_drop_count: the amount of the ore materials
|
# ore_drop_count: the amount of the ore materials
|
||||||
# exp: the exp to drop
|
|
||||||
default:loot_table/ore:
|
default:loot_table/ore:
|
||||||
pools:
|
pools:
|
||||||
- rolls: 1
|
- rolls: 1
|
||||||
@@ -203,8 +202,6 @@ templates:
|
|||||||
formula:
|
formula:
|
||||||
type: ore_drops
|
type: ore_drops
|
||||||
- type: explosion_decay
|
- type: explosion_decay
|
||||||
- type: drop_exp
|
|
||||||
count: ${exp:-2~4}
|
|
||||||
|
|
||||||
# Using Silk Touch or shears will cause the leaves block itself to drop.
|
# Using Silk Touch or shears will cause the leaves block itself to drop.
|
||||||
# Using Fortune, however, increases the drop rates of sticks and saplings.
|
# Using Fortune, however, increases the drop rates of sticks and saplings.
|
||||||
|
|||||||
Reference in New Issue
Block a user