9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2026-01-04 15:41:38 +00:00

添加软碰撞体积

This commit is contained in:
XiaoMoMi
2025-04-18 20:52:04 +08:00
parent 3ba9c8d9bd
commit 9b5d20f212
8 changed files with 95 additions and 12 deletions

View File

@@ -10,5 +10,6 @@ public class BukkitHitBoxTypes extends HitBoxTypes {
register(INTERACTION, InteractionHitBox.FACTORY);
register(SHULKER, ShulkerHitBox.FACTORY);
register(HAPPY_GHAST, HappyGhastHitBox.FACTORY);
register(CUSTOM, CustomHitBox.FACTORY);
}
}

View File

@@ -0,0 +1,87 @@
package net.momirealms.craftengine.bukkit.entity.furniture.hitbox;
import net.momirealms.craftengine.bukkit.entity.data.BaseEntityData;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.core.entity.furniture.*;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.entity.EntityType;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class CustomHitBox extends AbstractHitBox {
public static final Factory FACTORY = new Factory();
private final float scale;
private final EntityType entityType;
private final List<Object> cachedValues = new ArrayList<>();
public CustomHitBox(Seat[] seats, Vector3f position, EntityType type, float scale) {
super(seats, position);
this.scale = scale;
this.entityType = type;
BaseEntityData.NoGravity.addEntityDataIfNotDefaultValue(true, this.cachedValues);
BaseEntityData.Silent.addEntityDataIfNotDefaultValue(true, this.cachedValues);
BaseEntityData.SharedFlags.addEntityDataIfNotDefaultValue((byte) 0x20, this.cachedValues);
}
public EntityType entityType() {
return entityType;
}
public float scale() {
return scale;
}
@Override
public Key type() {
return HitBoxTypes.CUSTOM;
}
@Override
public void addSpawnPackets(int[] entityId, double x, double y, double z, float yaw, Quaternionf conjugated, BiConsumer<Object, Boolean> packets) {
Vector3f offset = conjugated.transform(new Vector3f(position()));
try {
packets.accept(Reflections.constructor$ClientboundAddEntityPacket.newInstance(
entityId[0], UUID.randomUUID(), x + offset.x, y + offset.y, z - offset.z, 0, yaw,
FastNMS.INSTANCE.toNMSEntityType(this.entityType), 0, Reflections.instance$Vec3$Zero, 0
), true);
packets.accept(Reflections.constructor$ClientboundSetEntityDataPacket.newInstance(entityId[0], List.copyOf(this.cachedValues)), true);
if (VersionHelper.isVersionNewerThan1_20_5() && this.scale != 1) {
Object attributeInstance = Reflections.constructor$AttributeInstance.newInstance(Reflections.instance$Holder$Attribute$scale, (Consumer<?>) (o) -> {});
Reflections.method$AttributeInstance$setBaseValue.invoke(attributeInstance, this.scale);
packets.accept(Reflections.constructor$ClientboundUpdateAttributesPacket0.newInstance(entityId[0], Collections.singletonList(attributeInstance)), false);
}
} catch (ReflectiveOperationException e) {
throw new RuntimeException("Failed to construct custom hitbox spawn packet", e);
}
}
@Override
public int[] acquireEntityIds(Supplier<Integer> entityIdSupplier) {
return new int[] {entityIdSupplier.get()};
}
public static class Factory implements HitBoxFactory {
@Override
public HitBox create(Map<String, Object> arguments) {
Vector3f position = MiscUtils.getVector3f(arguments.getOrDefault("position", "0"));
float scale = MiscUtils.getAsFloat(arguments.getOrDefault("scale", "1"));
EntityType entityType = Registry.ENTITY_TYPE.get(new NamespacedKey("minecraft", (String) arguments.getOrDefault("entity-type", "slime")));
if (entityType == null) {
throw new IllegalArgumentException("EntityType not found: " + arguments.get("entity-type"));
}
return new CustomHitBox(HitBoxFactory.getSeats(arguments), position, entityType, scale);
}
}
}

View File

@@ -55,7 +55,7 @@ public class InteractionHitBox extends AbstractHitBox {
), true);
packets.accept(Reflections.constructor$ClientboundSetEntityDataPacket.newInstance(entityId[0], List.copyOf(this.cachedValues)), true);
} catch (ReflectiveOperationException e) {
throw new RuntimeException("Failed to construct hitbox spawn packet", e);
throw new RuntimeException("Failed to construct interaction hitbox spawn packet", e);
}
}

View File

@@ -140,9 +140,9 @@ public class ShulkerHitBox extends AbstractHitBox {
entityIds[1], (short) 0, ya, (short) 0, true
), false);
}
if (VersionHelper.isVersionNewerThan1_20_5()) {
if (VersionHelper.isVersionNewerThan1_20_5() && this.scale != 1) {
Object attributeInstance = Reflections.constructor$AttributeInstance.newInstance(Reflections.instance$Holder$Attribute$scale, (Consumer<?>) (o) -> {});
Reflections.method$AttributeInstance$setBaseValue.invoke(attributeInstance, scale);
Reflections.method$AttributeInstance$setBaseValue.invoke(attributeInstance, this.scale);
packets.accept(Reflections.constructor$ClientboundUpdateAttributesPacket0.newInstance(entityIds[1], Collections.singletonList(attributeInstance)), false);
}
if (this.interactionEntity) {

View File

@@ -43,6 +43,7 @@ import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Pose;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;

View File

@@ -1,14 +1,11 @@
package net.momirealms.craftengine.bukkit.plugin.command.feature;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.entity.Pose;
import org.incendo.cloud.Command;
public class TestCommand extends BukkitCommandFeature<CommandSender> {
@@ -23,10 +20,6 @@ public class TestCommand extends BukkitCommandFeature<CommandSender> {
.senderType(Player.class)
.handler(context -> {
Player player = context.sender();
ItemStack itemStack = new ItemStack(Material.STONE);
Item<ItemStack> wrapped = BukkitItemManager.instance().wrap(itemStack);
wrapped.lore(null);
player.getInventory().addItem(wrapped.load());
});
}