9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-25 09:59:20 +00:00

Merge branch 'Xiao-MoMi:dev' into dev

This commit is contained in:
jhqwqmc
2025-03-25 17:06:13 +08:00
committed by GitHub
7 changed files with 84 additions and 9 deletions

View File

@@ -178,7 +178,7 @@ public final class CraftEngineBlocks {
BukkitServerPlayer serverPlayer = BukkitCraftEngine.instance().adapt(player);
if (player != null) {
builder.withParameter(LootParameters.PLAYER, serverPlayer);
builder.withParameter(LootParameters.TOOL, serverPlayer.getItemInHand(InteractionHand.MAIN_HAND));
builder.withOptionalParameter(LootParameters.TOOL, serverPlayer.getItemInHand(InteractionHand.MAIN_HAND));
}
for (Item<?> item : state.getDrops(builder, world)) {
world.dropItemNaturally(vec3d, item);

View File

@@ -246,7 +246,7 @@ public class CraftEngineFurniture {
builder.withParameter(LootParameters.WORLD, world);
if (player != null) {
builder.withParameter(LootParameters.PLAYER, player);
builder.withParameter(LootParameters.TOOL, player.getItemInHand(InteractionHand.MAIN_HAND));
builder.withOptionalParameter(LootParameters.TOOL, player.getItemInHand(InteractionHand.MAIN_HAND));
}
List<Item<ItemStack>> items = lootTable.getRandomItems(builder.build(), world);
for (Item<ItemStack> item : items) {

View File

@@ -138,7 +138,7 @@ public class BlockEventListener implements Listener {
builder.withParameter(LootParameters.WORLD, world);
builder.withParameter(LootParameters.LOCATION, vec3d);
builder.withParameter(LootParameters.PLAYER, serverPlayer);
builder.withParameter(LootParameters.TOOL, itemInHand);
builder.withOptionalParameter(LootParameters.TOOL, itemInHand);
for (Item<Object> item : state.getDrops(builder, world)) {
world.dropItemNaturally(vec3d, item);
}
@@ -159,7 +159,7 @@ public class BlockEventListener implements Listener {
builder.withParameter(LootParameters.WORLD, world);
builder.withParameter(LootParameters.LOCATION, vec3d);
builder.withParameter(LootParameters.PLAYER, serverPlayer);
builder.withParameter(LootParameters.TOOL, serverPlayer.getItemInHand(InteractionHand.MAIN_HAND));
builder.withOptionalParameter(LootParameters.TOOL, serverPlayer.getItemInHand(InteractionHand.MAIN_HAND));
ContextHolder contextHolder = builder.build();
for (LootTable<?> lootTable : it.lootTables()) {
for (Item<?> item : lootTable.getRandomItems(contextHolder, world)) {

View File

@@ -1,32 +1,63 @@
package net.momirealms.craftengine.bukkit.loot;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.bukkit.util.KeyUtils;
import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.entity.player.InteractionHand;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.loot.LootTable;
import net.momirealms.craftengine.core.loot.VanillaLoot;
import net.momirealms.craftengine.core.loot.VanillaLootManager;
import net.momirealms.craftengine.core.loot.parameter.LootParameters;
import net.momirealms.craftengine.core.pack.Pack;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.PreConditions;
import net.momirealms.craftengine.core.util.VersionHelper;
import net.momirealms.craftengine.core.util.context.ContextHolder;
import net.momirealms.craftengine.core.world.Vec3d;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import java.nio.file.Path;
import java.util.*;
public class BukkitVanillaLootManager implements VanillaLootManager {
private final CraftEngine plugin;
// note: block listeners are in BlockEventListener to reduce performance cost
public class BukkitVanillaLootManager implements VanillaLootManager, Listener {
private final BukkitCraftEngine plugin;
private final Map<Integer, VanillaLoot> blockLoots;
private final Map<Key, VanillaLoot> entityLoots;
public BukkitVanillaLootManager(CraftEngine plugin) {
public BukkitVanillaLootManager(BukkitCraftEngine plugin) {
this.plugin = plugin;
this.blockLoots = new HashMap<>();
this.entityLoots = new HashMap<>();
}
@Override
public void delayedInit() {
Bukkit.getPluginManager().registerEvents(this, plugin.bootstrap());
}
@Override
public void disable() {
HandlerList.unregisterAll(this);
}
@Override
public void unload() {
this.blockLoots.clear();
this.entityLoots.clear();
}
@Override
@@ -34,6 +65,37 @@ public class BukkitVanillaLootManager implements VanillaLootManager {
return Optional.ofNullable(this.blockLoots.get(vanillaBlockState));
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onEntityDeath(EntityDeathEvent event) {
Entity entity = event.getEntity();
Key key = KeyUtils.namespacedKey2Key(entity.getType().getKey());
Optional.ofNullable(this.entityLoots.get(key)).ifPresent(loot -> {
if (loot.override()) {
event.getDrops().clear();
event.setDroppedExp(0);
}
Location location = entity.getLocation();
net.momirealms.craftengine.core.world.World world = new BukkitWorld(entity.getWorld());
Vec3d vec3d = new Vec3d(location.getBlockX() + 0.5, location.getBlockY() + 0.5, location.getBlockZ() + 0.5);
ContextHolder.Builder builder = ContextHolder.builder();
builder.withParameter(LootParameters.WORLD, world);
builder.withParameter(LootParameters.LOCATION, vec3d);
if (VersionHelper.isVersionNewerThan1_20_5()) {
if (event.getDamageSource().getCausingEntity() instanceof Player player) {
BukkitServerPlayer serverPlayer = this.plugin.adapt(player);
builder.withParameter(LootParameters.PLAYER, serverPlayer);
builder.withOptionalParameter(LootParameters.TOOL, serverPlayer.getItemInHand(InteractionHand.MAIN_HAND));
}
}
ContextHolder contextHolder = builder.build();
for (LootTable<?> lootTable : loot.lootTables()) {
for (Item<?> item : lootTable.getRandomItems(contextHolder, world)) {
world.dropItemNaturally(vec3d, item);
}
}
});
}
@Override
public void parseSection(Pack pack, Path path, Key id, Map<String, Object> section) {
String type = (String) section.get("type");
@@ -68,6 +130,14 @@ public class BukkitVanillaLootManager implements VanillaLootManager {
}
}
}
case ENTITY -> {
for (String target : targets) {
Key key = Key.of(target);
VanillaLoot vanillaLoot = this.entityLoots.computeIfAbsent(key, k -> new VanillaLoot(VanillaLoot.Type.ENTITY));
vanillaLoot.addLootTable(lootTable);
if (override) vanillaLoot.override(true);
}
}
}
}
}

View File

@@ -35,6 +35,7 @@ public class VanillaLoot {
}
public enum Type {
BLOCK
BLOCK,
ENTITY
}
}

View File

@@ -19,5 +19,7 @@ public interface VanillaLootManager extends ConfigSectionParser, Reloadable {
return CONFIG_SECTION_NAME;
}
void delayedInit();
Optional<VanillaLoot> getBlockLoot(int blockState);
}

View File

@@ -134,6 +134,7 @@ public abstract class CraftEngine implements Plugin {
this.packManager.delayedInit();
this.furnitureManager.delayedInit();
this.imageManager.delayedInit();
this.vanillaLootManager.delayedInit();
});
}
@@ -153,6 +154,7 @@ public abstract class CraftEngine implements Plugin {
if (this.itemBrowserManager != null) this.itemBrowserManager.disable();
if (this.guiManager != null) this.guiManager.disable();
if (this.soundManager != null) this.soundManager.disable();
if (this.vanillaLootManager != null) this.vanillaLootManager.disable();
if (this.scheduler != null) this.scheduler.shutdownScheduler();
if (this.scheduler != null) this.scheduler.shutdownExecutor();
ResourcePackHost.instance().disable();