mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
限制摆放
This commit is contained in:
@@ -32,7 +32,7 @@ public class InteractionFurnitureHitbox extends AbstractFurnitureHitBox {
|
||||
int interactionId = CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet();
|
||||
this.spawnPacket = FastNMS.INSTANCE.constructor$ClientboundBundlePacket(List.of(
|
||||
FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
|
||||
interactionId, UUID.randomUUID(), position.x, position.y, position.z, 0, position.yRot,
|
||||
interactionId, UUID.randomUUID(), pos.x, pos.y, pos.z, 0, position.yRot,
|
||||
MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0
|
||||
),
|
||||
FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(interactionId, config.cachedValues())
|
||||
|
||||
@@ -8,9 +8,7 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.util.EventUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||
import net.momirealms.craftengine.core.entity.furniture.FurnitureConfig;
|
||||
import net.momirealms.craftengine.core.entity.furniture.FurnitureDataAccessor;
|
||||
import net.momirealms.craftengine.core.entity.furniture.FurnitureVariant;
|
||||
import net.momirealms.craftengine.core.entity.furniture.*;
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitBoxConfig;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionResult;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
@@ -26,10 +24,8 @@ import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
|
||||
import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Cancellable;
|
||||
import net.momirealms.craftengine.core.util.ItemUtils;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.plugin.logger.Debugger;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
import net.momirealms.craftengine.core.world.collision.AABB;
|
||||
@@ -38,17 +34,17 @@ import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
|
||||
public class FurnitureItemBehavior extends ItemBehavior {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
private static final Set<String> ALLOWED_ANCHOR_TYPES = Set.of("wall", "ceiling", "ground");
|
||||
private final Key id;
|
||||
private final Map<AnchorType, Rule> rules;
|
||||
|
||||
public FurnitureItemBehavior(Key id) {
|
||||
public FurnitureItemBehavior(Key id, Map<AnchorType, Rule> rules) {
|
||||
this.id = id;
|
||||
this.rules = rules;
|
||||
}
|
||||
|
||||
public Key furnitureId() {
|
||||
@@ -67,12 +63,24 @@ public class FurnitureItemBehavior extends ItemBehavior {
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
Direction clickedFace = context.getClickedFace();
|
||||
AnchorType anchorType = switch (clickedFace) {
|
||||
case EAST, WEST, NORTH, SOUTH -> AnchorType.WALL;
|
||||
case UP -> AnchorType.GROUND;
|
||||
case DOWN -> AnchorType.CEILING;
|
||||
};
|
||||
|
||||
FurnitureConfig customFurniture = optionalCustomFurniture.get();
|
||||
FurnitureVariant variant = customFurniture.anyVariant();
|
||||
FurnitureVariant variant = customFurniture.getVariant(anchorType.variantName());
|
||||
if (variant == null) {
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
Rule rule = this.rules.get(anchorType);
|
||||
if (rule == null) {
|
||||
rule = Rule.DEFAULT;
|
||||
}
|
||||
|
||||
Player player = context.getPlayer();
|
||||
if (player != null && player.isAdventureMode()) {
|
||||
return InteractionResult.FAIL;
|
||||
@@ -80,14 +88,27 @@ public class FurnitureItemBehavior extends ItemBehavior {
|
||||
|
||||
Vec3d clickedPosition = context.getClickLocation();
|
||||
|
||||
// get position and rotation for placement
|
||||
Vec3d finalPlacePosition;
|
||||
double furnitureYaw;
|
||||
if (anchorType == AnchorType.WALL) {
|
||||
furnitureYaw = Direction.getYaw(clickedFace);
|
||||
if (clickedFace == Direction.EAST || clickedFace == Direction.WEST) {
|
||||
Pair<Double, Double> xz = rule.alignmentRule().apply(Pair.of(clickedPosition.y(), clickedPosition.z()));
|
||||
finalPlacePosition = new Vec3d(clickedPosition.x(), xz.left(), xz.right());
|
||||
} else {
|
||||
Pair<Double, Double> xz = rule.alignmentRule().apply(Pair.of(clickedPosition.x(), clickedPosition.y()));
|
||||
finalPlacePosition = new Vec3d(xz.left(), xz.right(), clickedPosition.z());
|
||||
}
|
||||
} else {
|
||||
furnitureYaw = rule.rotationRule().apply(180 + (player != null ? player.yRot() : 0));
|
||||
Pair<Double, Double> xz = rule.alignmentRule().apply(Pair.of(clickedPosition.x(), clickedPosition.z()));
|
||||
finalPlacePosition = new Vec3d(xz.left(), clickedPosition.y(), xz.right());
|
||||
}
|
||||
|
||||
// trigger event
|
||||
org.bukkit.entity.Player bukkitPlayer = player != null ? (org.bukkit.entity.Player) player.platformPlayer() : null;
|
||||
World world = (World) context.getLevel().platformWorld();
|
||||
|
||||
// get position and rotation for placement
|
||||
Vec3d finalPlacePosition = clickedPosition;
|
||||
double furnitureYaw = 180 + (player != null ? player.yRot() : 0);
|
||||
|
||||
Location furnitureLocation = new Location(world, finalPlacePosition.x(), finalPlacePosition.y(), finalPlacePosition.z(), (float) furnitureYaw, 0);
|
||||
WorldPosition furniturePos = LocationUtils.toWorldPosition(furnitureLocation);
|
||||
List<AABB> aabbs = new ArrayList<>();
|
||||
@@ -162,17 +183,59 @@ public class FurnitureItemBehavior extends ItemBehavior {
|
||||
if (id == null) {
|
||||
throw new LocalizedResourceConfigException("warning.config.item.behavior.furniture.missing_furniture", new IllegalArgumentException("Missing required parameter 'furniture' for furniture_item behavior"));
|
||||
}
|
||||
Map<String, Object> rulesMap = ResourceConfigUtils.getAsMapOrNull(arguments.get("rules"), "rules");
|
||||
Key furnitureId;
|
||||
if (id instanceof Map<?,?> map) {
|
||||
Map<String, Object> furnitureSection;
|
||||
if (map.containsKey(key.toString())) {
|
||||
// 防呆
|
||||
BukkitFurnitureManager.instance().parser().addPendingConfigSection(new PendingConfigSection(pack, path, node, key, MiscUtils.castToMap(map.get(key.toString()), false)));
|
||||
furnitureSection = MiscUtils.castToMap(map.get(key.toString()), false);
|
||||
BukkitFurnitureManager.instance().parser().addPendingConfigSection(new PendingConfigSection(pack, path, node, key, furnitureSection));
|
||||
} else {
|
||||
BukkitFurnitureManager.instance().parser().addPendingConfigSection(new PendingConfigSection(pack, path, node, key, MiscUtils.castToMap(map, false)));
|
||||
furnitureSection = MiscUtils.castToMap(map, false);
|
||||
BukkitFurnitureManager.instance().parser().addPendingConfigSection(new PendingConfigSection(pack, path, node, key, furnitureSection));
|
||||
}
|
||||
furnitureId = key;
|
||||
// 兼容老版本
|
||||
if (rulesMap == null) {
|
||||
Map<String, Object> placementSection = ResourceConfigUtils.getAsMapOrNull(furnitureSection.get("placement"), "placement");
|
||||
if (placementSection != null) {
|
||||
rulesMap = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : placementSection.entrySet()) {
|
||||
if (entry.getValue() instanceof Map<?, ?> innerMap) {
|
||||
if (innerMap.containsKey("rules")) {
|
||||
Map<String, Object> rules = ResourceConfigUtils.getAsMap(innerMap.get("rules"), "rules");
|
||||
if (ALLOWED_ANCHOR_TYPES.contains(entry.getKey())) {
|
||||
rulesMap.put(entry.getKey(), rules);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new FurnitureItemBehavior(key);
|
||||
} else {
|
||||
return new FurnitureItemBehavior(Key.of(id.toString()));
|
||||
furnitureId = Key.of(id.toString());
|
||||
}
|
||||
Map<AnchorType, Rule> rules = new EnumMap<>(AnchorType.class);
|
||||
if (rulesMap != null) {
|
||||
for (Map.Entry<String, Object> entry : rulesMap.entrySet()) {
|
||||
try {
|
||||
AnchorType type = AnchorType.valueOf(entry.getKey().toUpperCase(Locale.ROOT));
|
||||
Map<String, Object> ruleSection = MiscUtils.castToMap(entry.getValue(), true);
|
||||
rules.put(type, new Rule(
|
||||
ResourceConfigUtils.getAsEnum(ruleSection.get("alignment"), AlignmentRule.class, AlignmentRule.ANY),
|
||||
ResourceConfigUtils.getAsEnum(ruleSection.get("rotation"), RotationRule.class, RotationRule.ANY)
|
||||
));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
Debugger.FURNITURE.debug(() -> "Invalid anchor type: " + entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
return new FurnitureItemBehavior(furnitureId, rules);
|
||||
}
|
||||
}
|
||||
|
||||
public record Rule(AlignmentRule alignmentRule, RotationRule rotationRule) {
|
||||
public static final Rule DEFAULT = new Rule(AlignmentRule.ANY, RotationRule.ANY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@ items:
|
||||
model: minecraft:item/custom/bench
|
||||
behavior:
|
||||
type: furniture_item
|
||||
rules:
|
||||
ground:
|
||||
rotation: four
|
||||
alignment: center
|
||||
furniture:
|
||||
settings:
|
||||
item: default:bench
|
||||
@@ -17,8 +21,8 @@ items:
|
||||
loot-spawn-offset: 0.5,0.5,0
|
||||
elements:
|
||||
- item: default:bench
|
||||
display-transform: NONE
|
||||
billboard: FIXED
|
||||
display-transform: none
|
||||
billboard: fixed
|
||||
position: 0.5,0,0
|
||||
translation: 0,0.5,0
|
||||
shadow-radius: 1
|
||||
|
||||
@@ -7,6 +7,16 @@ items:
|
||||
behavior:
|
||||
type: furniture_item
|
||||
furniture: default:flower_basket
|
||||
rules:
|
||||
ground:
|
||||
rotation: any
|
||||
alignment: any
|
||||
wall:
|
||||
rotation: any
|
||||
alignment: any
|
||||
ceiling:
|
||||
rotation: any
|
||||
alignment: any
|
||||
default:flower_basket_ground:
|
||||
material: nether_brick
|
||||
model: minecraft:item/custom/flower_basket_ground
|
||||
@@ -27,15 +37,12 @@ furniture:
|
||||
template: default:loot_table/furniture
|
||||
arguments:
|
||||
item: default:flower_basket
|
||||
placement:
|
||||
variants:
|
||||
ground:
|
||||
rules:
|
||||
rotation: ANY
|
||||
alignment: ANY
|
||||
elements:
|
||||
- item: default:flower_basket_ground
|
||||
display-transform: NONE
|
||||
billboard: FIXED
|
||||
display-transform: none
|
||||
billboard: fixed
|
||||
position: 0,0,0
|
||||
translation: 0,0.5,0
|
||||
shadow-radius: 0.5
|
||||
@@ -50,12 +57,10 @@ furniture:
|
||||
height: 0.5
|
||||
interactive: true
|
||||
wall:
|
||||
rules:
|
||||
alignment: ANY
|
||||
elements:
|
||||
- item: default:flower_basket_wall
|
||||
display-transform: NONE
|
||||
billboard: FIXED
|
||||
display-transform: none
|
||||
billboard: fixed
|
||||
position: 0,0,0.2
|
||||
translation: 0,0,0
|
||||
hitboxes:
|
||||
@@ -76,13 +81,10 @@ furniture:
|
||||
height: 0.75
|
||||
interactive: true
|
||||
ceiling:
|
||||
rules:
|
||||
rotation: ANY
|
||||
alignment: ANY
|
||||
elements:
|
||||
- item: default:flower_basket_ceiling
|
||||
display-transform: NONE
|
||||
billboard: FIXED
|
||||
display-transform: none
|
||||
billboard: fixed
|
||||
position: 0,-0.46,0
|
||||
translation: 0,0,0
|
||||
hitboxes:
|
||||
|
||||
@@ -6,18 +6,19 @@ items:
|
||||
model: minecraft:item/custom/wooden_chair
|
||||
behavior:
|
||||
type: furniture_item
|
||||
rules:
|
||||
ground:
|
||||
rotation: any
|
||||
alignment: any
|
||||
furniture:
|
||||
settings:
|
||||
item: default:wooden_chair
|
||||
sounds:
|
||||
break: minecraft:block.bamboo_wood.break
|
||||
place: minecraft:block.bamboo_wood.place
|
||||
placement:
|
||||
variants:
|
||||
ground:
|
||||
loot-spawn-offset: 0,0.4,0
|
||||
rules:
|
||||
rotation: ANY
|
||||
alignment: ANY
|
||||
elements:
|
||||
- item: default:wooden_chair
|
||||
display-transform: NONE
|
||||
|
||||
@@ -1,21 +1,26 @@
|
||||
package net.momirealms.craftengine.core.entity.furniture;
|
||||
|
||||
@Deprecated(since = "0.0.66")
|
||||
public enum AnchorType {
|
||||
GROUND(0),
|
||||
WALL(1),
|
||||
CEILING(2);
|
||||
GROUND(0, "ground"),
|
||||
WALL(1, "wall"),
|
||||
CEILING(2, "ceiling");
|
||||
|
||||
private final int id;
|
||||
private final String variantName;
|
||||
|
||||
AnchorType(int id) {
|
||||
AnchorType(int id, String variantName) {
|
||||
this.id = id;
|
||||
this.variantName = variantName;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String variantName() {
|
||||
return variantName;
|
||||
}
|
||||
|
||||
public static AnchorType byId(int id) {
|
||||
return values()[id];
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public final class ResourceConfigUtils {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
return Enum.valueOf(clazz, o.toString().toUpperCase(Locale.ENGLISH));
|
||||
return Enum.valueOf(clazz, o.toString().toUpperCase(Locale.ROOT));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user