Skip to content

Commit 44c6e44

Browse files
committed
Fix entity spawning (spawn egg impl)
1 parent 9b63889 commit 44c6e44

File tree

9 files changed

+357
-119
lines changed

9 files changed

+357
-119
lines changed

server/src/main/java/org/cloudburstmc/server/entity/CloudEntity.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,13 @@ protected final void init(Location location) {
584584
this.level = (CloudLevel) location.getLevel();
585585
this.server = (CloudServer) location.getLevel().getServer();
586586

587+
this.position = location.getPosition();
588+
this.lastPosition = this.position;
589+
this.yaw = location.getYaw();
590+
this.pitch = location.getPitch();
591+
this.lastYaw = this.yaw;
592+
this.lastPitch = this.pitch;
593+
587594
this.boundingBox = new SimpleAxisAlignedBB(0, 0, 0, 0, 0, 0);
588595

589596
this.level.getChunkFuture(location.getChunkX(), location.getChunkZ()).whenComplete((chunk1, throwable) -> {
@@ -622,7 +629,9 @@ public void spawnTo(Player player) {
622629
}
623630

624631
public void spawnTo(CloudPlayer player) {
625-
if (!player.isChunkInView(this.chunk.getX(), this.chunk.getZ()) || !this.getViewers().add(player)) {
632+
boolean inView = player.isChunkInView(this.chunk.getX(), this.chunk.getZ());
633+
boolean added = inView && this.getViewers().add(player);
634+
if (!inView || !added) {
626635
// out of range or already spawned
627636
return;
628637
}
@@ -641,11 +650,12 @@ public void spawnTo(CloudPlayer player) {
641650
}
642651

643652
protected BedrockPacket createAddEntityPacket() {
653+
Vector3f pos = this.getPosition();
644654
AddEntityPacket addEntity = new AddEntityPacket();
645655
addEntity.setIdentifier(this.getType().getIdentifier().toString());
646656
addEntity.setUniqueEntityId(this.getUniqueId());
647-
addEntity.setRuntimeEntityId(this.getUniqueId());
648-
addEntity.setPosition(this.getPosition());
657+
addEntity.setRuntimeEntityId(this.getRuntimeId());
658+
addEntity.setPosition(Vector3f.from(pos.getX(), pos.getY() + this.getBaseOffset(), pos.getZ()));
649659
addEntity.setRotation(Vector2f.from(this.pitch, this.yaw));
650660
addEntity.setHeadRotation(this.yaw);
651661
addEntity.setMotion(this.getMotion());

server/src/main/java/org/cloudburstmc/server/entity/misc/EntityDroppedItem.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,11 @@ public void setPickupDelay(int pickupDelay) {
268268

269269
@Override
270270
public BedrockPacket createAddEntityPacket() {
271+
Vector3f pos = this.getPosition();
271272
AddItemEntityPacket addEntity = new AddItemEntityPacket();
272273
addEntity.setUniqueEntityId(this.getUniqueId());
273274
addEntity.setRuntimeEntityId(this.getRuntimeId());
274-
addEntity.setPosition(this.getPosition());
275+
addEntity.setPosition(Vector3f.from(pos.getX(), pos.getY() + this.getBaseOffset(), pos.getZ()));
275276
addEntity.setMotion(this.getMotion());
276277
this.data.putAllIn(addEntity.getMetadata());
277278
addEntity.setItemInHand(ItemUtils.toNetwork(this.getItem()));

server/src/main/java/org/cloudburstmc/server/entity/misc/EntityFireworksRocket.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ public EntityFireworksRocket(EntityType<FireworksRocket> type, Location location
3838
super(type, location);
3939
}
4040

41+
@Override
42+
protected float getBaseOffset() {
43+
return 0.49f;
44+
}
45+
4146
@Override
4247
protected void initEntity() {
4348
super.initEntity();

server/src/main/java/org/cloudburstmc/server/entity/passive/EntitySheep.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ public String getName() {
5353

5454
@Override
5555
public void initEntity() {
56+
super.initEntity();
5657
this.setMaxHealth(8);
58+
this.data.set(COLOR, (byte) randomColor());
5759
}
5860

5961
@Override

server/src/main/java/org/cloudburstmc/server/item/ItemUtils.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ public class ItemUtils {
4040
private static final Cache<ItemStack, NbtMap> ITEM_CACHE = CacheBuilder.newBuilder().weakKeys().softValues().build();
4141

4242
public static NbtMap serializeItem(ItemStack item) {
43+
if (item == null || item.isEmpty()) {
44+
return NbtMap.builder()
45+
.putString("Name", "minecraft:air")
46+
.putByte("Count", (byte) 0)
47+
.putShort("Damage", (short) 0)
48+
.build();
49+
}
50+
4351
NbtMapBuilder nbtTag = NbtMap.builder();
4452

4553
nbtTag.putString("Name", item.getType().getId().toString())
@@ -108,11 +116,17 @@ public static ItemStack deserializeItem(NbtMap tag) {
108116
return ItemStack.EMPTY;
109117
}
110118

111-
ItemStackBuilder builder = ItemUtils.deserializeItem(
119+
ItemStack base = ItemUtils.deserializeItem(
112120
Identifier.parse(tag.getString("Name")),
113121
tag.getShort("Damage", (short) 0),
114122
tag.getByte("Count"),
115-
tag.getCompound("tag", NbtMap.EMPTY)).toBuilder();
123+
tag.getCompound("tag", NbtMap.EMPTY));
124+
125+
if (base.isEmpty()) {
126+
return ItemStack.EMPTY;
127+
}
128+
129+
ItemStackBuilder builder = base.toBuilder();
116130

117131
if (tag.containsKey("CanPlaceOn", NbtType.LIST)) {
118132
List<BlockType> list = tag.getList("CanPlaceOn", NbtType.STRING, Collections.emptyList()).stream().map(Identifier::parse).map(BlockType::of).toList();
@@ -351,7 +365,7 @@ public static UUID getMultiItemHash(List<ItemStack> items) {
351365
ByteBuffer buffer = ByteBuffer.allocate(items.size() * 8);
352366
for (ItemStack item : items) {
353367
if (item != null && !item.isEmpty())
354-
buffer.putInt(getItemHash((ItemStack) item));
368+
buffer.putInt(getItemHash(item));
355369
}
356370
return UUID.nameUUIDFromBytes(buffer.array());
357371
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.cloudburstmc.server.item.component;
2+
3+
import lombok.experimental.UtilityClass;
4+
import org.cloudburstmc.api.entity.EntityType;
5+
import org.cloudburstmc.api.item.ItemStack;
6+
import org.cloudburstmc.api.item.component.BooleanItemHandler;
7+
import org.cloudburstmc.api.item.component.UseOnHandler;
8+
import org.cloudburstmc.api.level.Location;
9+
import org.cloudburstmc.api.player.Player;
10+
import org.cloudburstmc.server.entity.CloudEntity;
11+
import org.cloudburstmc.server.registry.EntityRegistry;
12+
13+
@UtilityClass
14+
public class SpawnEggItemHandlers {
15+
16+
public static final BooleanItemHandler CAN_BE_USED = (item) -> true;
17+
18+
public static UseOnHandler useOn(EntityType<?> entityType) {
19+
return (item, entity, blockPos, face, clickPos) -> {
20+
float spawnX = blockPos.getX() + 0.5f;
21+
float spawnY = blockPos.getY() + 1.0f;
22+
float spawnZ = blockPos.getZ() + 0.5f;
23+
24+
Location location = Location.from(spawnX, spawnY, spawnZ, entity.getLevel());
25+
CloudEntity spawned = (CloudEntity) EntityRegistry.get().newEntity(entityType, location);
26+
spawned.spawnToAll();
27+
28+
if (((Player) entity).isCreative()) {
29+
return item;
30+
}
31+
32+
ItemStack result = item.decreaseCount();
33+
return result.getCount() <= 0 ? ItemStack.EMPTY : result;
34+
};
35+
}
36+
}

server/src/main/java/org/cloudburstmc/server/item/data/serializer/EntityTypeSerializer.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,15 @@
77
import org.cloudburstmc.nbt.NbtMapBuilder;
88
import org.cloudburstmc.server.registry.EntityRegistry;
99

10-
@SuppressWarnings("rawtypes")
11-
public class EntityTypeSerializer implements ItemDataSerializer<EntityType> {
10+
public class EntityTypeSerializer implements ItemDataSerializer<EntityType<?>> {
1211

1312
@Override
14-
public void serialize(ItemStack item, NbtMapBuilder tag, EntityType value) {
13+
public void serialize(ItemStack item, NbtMapBuilder tag, EntityType<?> value) {
1514
tag.putString("ItemIdentifier", value.getIdentifier().toString());
1615
}
1716

1817
@Override
19-
public EntityType deserialize(Identifier id, NbtMap tag) {
18+
public EntityType<?> deserialize(Identifier id, NbtMap tag) {
2019
return EntityRegistry.get().getEntityType(Identifier.parse(tag.getString("ItemIdentifier", "unknown")));
2120
}
2221
}

server/src/main/java/org/cloudburstmc/server/level/CloudLevel.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -272,21 +272,21 @@ public int getTickRate() {
272272
return tickRate;
273273
}
274274

275-
public int getTickRateTime() {
276-
return tickRateTime;
277-
}
278-
279275
public void setTickRate(int tickRate) {
280276
this.tickRate = tickRate;
281277
}
282278

283-
public void init() {
279+
public int getTickRateTime() {
280+
return tickRateTime;
284281
}
285282

286283
/*public BlockMetadataStore getBlockMetadata() {
287284
return this.blockMetadata;
288285
}*/
289286

287+
public void init() {
288+
}
289+
290290
public CloudServer getServer() {
291291
return server;
292292
}
@@ -311,8 +311,6 @@ public void close() {
311311
// this.blockMetadata = null;
312312
}
313313

314-
private Vector3f mutableBlock;
315-
316314
public void addSound(Vector3i pos, Sound sound) {
317315
this.addSound(Vector3f.from(pos.getX() + 0.5f, pos.getY() + 0.5f, pos.getZ() + 0.5f), sound);
318316
}
@@ -1147,9 +1145,9 @@ public AxisAlignedBB[] getCollisionCubes(Entity entity, AxisAlignedBB bb, boolea
11471145
if (block == null) continue;
11481146
ComponentMap behaviors = block.getComponents();
11491147
AxisAlignedBB blockBB = behaviors.get(BlockComponents.GET_BOUNDING_BOX).execute(block.getState()).getOffsetBoundingBox(x, y, z);
1150-
if (this.blockRegistry.getComponent(block.getState().getType(), BlockComponents.SOLID).get() && blockBB.intersectsWith(bb)) {
1148+
if (this.blockRegistry.getComponent(block.getState().getType(), BlockComponents.SOLID).get() && blockBB.intersectsWith(bb)) {
11511149
collides.add(blockBB);
1152-
}
1150+
}
11531151
}
11541152
}
11551153
}
@@ -1768,14 +1766,16 @@ public ItemStack useItemOn(Vector3i vector, ItemStack item, Direction face, Vect
17681766
if (!ev.isCancelled()) {
17691767
targetBehaviors.get(BlockComponents.ON_TICK).execute(target, new Random());
17701768

1771-
if ((!player.isSneaking() || player.getInventory().getSelectedItem().isEmpty()) && targetBehaviors.get(BlockComponents.CAN_BE_USED).execute(target) && targetBehaviors.get(BlockComponents.USE).execute(target, player, face)) { //TODO: update the item from the behavior
1769+
boolean blockUsed = (!player.isSneaking() || player.getInventory().getSelectedItem().isEmpty()) && targetBehaviors.get(BlockComponents.CAN_BE_USED).execute(target) && targetBehaviors.get(BlockComponents.USE).execute(target, player, face);
1770+
if (blockUsed) { //TODO: update the item from the behavior
17721771
if (this.itemRegistry.getComponent(item.getType(), ItemComponents.IS_TOOL).execute(item) && item.get(ItemKeys.DAMAGE) >= itemBehaviors.get(ItemComponents.GET_MAX_DAMAGE).execute(item)) {
17731772
item = ItemStack.EMPTY;
17741773
}
17751774
return item;
17761775
}
17771776

1778-
if (itemBehaviors.get(ItemComponents.CAN_BE_USED).execute(item)) {
1777+
boolean itemCanBeUsed = itemBehaviors != null && itemBehaviors.get(ItemComponents.CAN_BE_USED).execute(item);
1778+
if (itemCanBeUsed) {
17791779
var result = itemBehaviors.get(ItemComponents.USE_ON).execute(item, player, target.getPosition(), face, clickPos);
17801780
// if (item.getCount() <= 0) {
17811781
// item = ItemStack.AIR;
@@ -1831,7 +1831,7 @@ public ItemStack useItemOn(Vector3i vector, ItemStack item, Direction face, Vect
18311831
if (handBB.intersectsWith(player.getBoundingBox())) {
18321832
++realCount;
18331833
}
1834-
1834+
18351835
Vector3f diff = ((CloudPlayer) player).getNextPosition().sub(player.getPosition());
18361836
if (diff.lengthSquared() > 0.00001) {
18371837
AxisAlignedBB bb = player.getBoundingBox().getOffsetBoundingBox(diff);
@@ -2304,7 +2304,7 @@ public Location getSafeSpawn(Location pos) {
23042304
blockState = chunk.getBlock(x, y + 1, z);
23052305
if (CloudBlockRegistry.REGISTRY.getComponent(blockState.getType(), BlockComponents.CAN_PASS_THROUGH).execute(this.getBlockState(x, y + 1, z))) {
23062306
blockState = chunk.getBlock(x, y, z);
2307-
if (CloudBlockRegistry.REGISTRY.getComponent(blockState.getType(), BlockComponents.CAN_PASS_THROUGH).execute(this.getBlockState(x, y, z))) {
2307+
if (CloudBlockRegistry.REGISTRY.getComponent(blockState.getType(), BlockComponents.CAN_PASS_THROUGH).execute(this.getBlockState(x, y, z))) {
23082308
return Location.from(pos.getX(), y, pos.getZ(), pos.getYaw(), pos.getPitch(), this);
23092309
}
23102310
}
@@ -2321,15 +2321,15 @@ public int getTime() {
23212321
return (int) this.levelData.getTime();
23222322
}
23232323

2324-
public boolean isDaytime() {
2325-
return this.skyLightSubtracted < 4;
2326-
}
2327-
23282324
public void setTime(int time) {
23292325
this.levelData.setTime(time);
23302326
this.sendTime();
23312327
}
23322328

2329+
public boolean isDaytime() {
2330+
return this.skyLightSubtracted < 4;
2331+
}
2332+
23332333
public long getCurrentTick() {
23342334
return this.levelData.getCurrentTick();
23352335
}

0 commit comments

Comments
 (0)