Skip to content

Commit

Permalink
Update FloatingTextParticle
Browse files Browse the repository at this point in the history
- Fixed name tag always visible
- Fixed set invisible not sending update
- Using armor stand instead of player entity for better performance
  • Loading branch information
PetteriM1 committed Jul 12, 2024
1 parent 1064456 commit ab419d1
Showing 1 changed file with 73 additions and 68 deletions.
141 changes: 73 additions & 68 deletions src/main/java/cn/nukkit/level/particle/FloatingTextParticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,25 @@

import cn.nukkit.entity.Entity;
import cn.nukkit.entity.data.EntityMetadata;
import cn.nukkit.entity.data.Skin;
import cn.nukkit.item.Item;
import cn.nukkit.level.Level;
import cn.nukkit.level.Location;
import cn.nukkit.math.Vector3;
import cn.nukkit.network.protocol.*;
import cn.nukkit.utils.SerializedImage;
import com.google.common.base.Strings;

import java.util.ArrayList;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;

/**
* Created on 2015/11/21 by xtypr.
* Package cn.nukkit.level.particle in project Nukkit .
*/
public class FloatingTextParticle extends Particle {
private static final Skin EMPTY_SKIN = new Skin();
private static final SerializedImage SKIN_DATA = SerializedImage.fromLegacy(new byte[8192]);

static {
EMPTY_SKIN.setSkinData(SKIN_DATA);
EMPTY_SKIN.generateSkinId("FloatingText");
}

protected UUID uuid = UUID.randomUUID();
protected final Level level;
protected long entityId = -1;
protected boolean invisible = false;
protected String title;
protected String text;
protected EntityMetadata metadata = new EntityMetadata();

public FloatingTextParticle(Location location, String title) {
Expand All @@ -53,110 +42,126 @@ public FloatingTextParticle(Vector3 pos, String title, String text) {
private FloatingTextParticle(Level level, Vector3 pos, String title, String text) {
super(pos.x, pos.y, pos.z);
this.level = level;
this.title = title;
this.text = text;

long flags = 0;
flags ^= 1 << Entity.DATA_FLAG_NO_AI;
flags ^= 1 << Entity.DATA_FLAG_CAN_SHOW_NAMETAG;

long flags = (
1L << Entity.DATA_FLAG_NO_AI
);
metadata.putLong(Entity.DATA_FLAGS, flags)
.putLong(Entity.DATA_LEAD_HOLDER_EID,-1)
.putFloat(Entity.DATA_SCALE, 0.01f) //zero causes problems on debug builds?
this.metadata.putLong(Entity.DATA_FLAGS, flags)
.putLong(Entity.DATA_LEAD_HOLDER_EID, -1)
.putByte(Entity.DATA_ALWAYS_SHOW_NAMETAG, 1)
.putFloat(Entity.DATA_SCALE, 0.01f) // Zero causes problems on debug builds?
.putFloat(Entity.DATA_BOUNDING_BOX_HEIGHT, 0.01f)
.putFloat(Entity.DATA_BOUNDING_BOX_WIDTH, 0.01f);
if (!Strings.isNullOrEmpty(title)) {
metadata.putString(Entity.DATA_NAMETAG, title);
}
if (!Strings.isNullOrEmpty(text)) {
metadata.putString(Entity.DATA_SCORE_TAG, text);
}

updateNameTag();
}

public String getText() {
return metadata.getString(Entity.DATA_SCORE_TAG);
return this.text == null ? "" : this.text;
}

public void setText(String text) {
this.metadata.putString(Entity.DATA_SCORE_TAG, text);
this.text = text;
updateNameTag();
sendMetadata();
}

public String getTitle() {
return metadata.getString(Entity.DATA_NAMETAG);
return this.title == null ? "" : this.title;
}

public void setTitle(String title) {
this.metadata.putString(Entity.DATA_NAMETAG, title);
this.title = title;
updateNameTag();
sendMetadata();
}

private void updateNameTag() {
// Score tag only works on player
boolean hasTitle = !Strings.isNullOrEmpty(this.title);
boolean hasText = !Strings.isNullOrEmpty(this.text);
String tag = "";
if (hasTitle) {
tag += this.title;
if (hasText) {
tag += "\n";
}
}
if (hasText) {
tag += this.text;
}
this.metadata.putString(Entity.DATA_NAMETAG, tag);
}

private void sendMetadata() {
if (level != null) {
if (this.level != null) {
SetEntityDataPacket packet = new SetEntityDataPacket();
packet.eid = entityId;
packet.metadata = metadata;
level.addChunkPacket(getChunkX(), getChunkZ(), packet);
packet.metadata = this.metadata;

this.level.addChunkPacket(getChunkX(), getChunkZ(), packet);
}
}

public boolean isInvisible() {
return invisible;
return this.invisible;
}

public void setInvisible(boolean invisible) {
this.invisible = invisible;

if (this.level != null) {
if (invisible) {
this.level.addChunkPacket(getChunkX(), getChunkZ(), getRemovePacket());
} else {
this.level.addChunkPacket(getChunkX(), getChunkZ(), getAddPacket());
}
}
}

public void setInvisible() {
this.setInvisible(true);
}

public long getEntityId() {
return entityId;
return this.entityId;
}

@Override
public DataPacket[] encode() {
ArrayList<DataPacket> packets = new ArrayList<>();

if (this.entityId == -1) {
this.entityId = 1095216660480L + ThreadLocalRandom.current().nextLong(0, 0x7fffffffL);
this.entityId = Entity.entityCount++;
} else {
RemoveEntityPacket pk = new RemoveEntityPacket();
pk.eid = this.entityId;

packets.add(pk);
packets.add(getRemovePacket());
}

if (!this.invisible) {
PlayerListPacket.Entry[] entry = {new PlayerListPacket.Entry(uuid, entityId,
metadata.getString(Entity.DATA_NAMETAG), EMPTY_SKIN)};
PlayerListPacket playerAdd = new PlayerListPacket();
playerAdd.entries = entry;
playerAdd.type = PlayerListPacket.TYPE_ADD;
packets.add(playerAdd);

AddPlayerPacket pk = new AddPlayerPacket();
pk.uuid = uuid;
pk.username = "";
pk.entityUniqueId = this.entityId;
pk.entityRuntimeId = this.entityId;
pk.x = (float) this.x;
pk.y = (float) (this.y - 0.75);
pk.z = (float) this.z;
pk.speedX = 0;
pk.speedY = 0;
pk.speedZ = 0;
pk.yaw = 0;
pk.pitch = 0;
pk.metadata = this.metadata;
pk.item = Item.get(Item.AIR);
packets.add(pk);

PlayerListPacket playerRemove = new PlayerListPacket();
playerRemove.entries = entry;
playerRemove.type = PlayerListPacket.TYPE_REMOVE;
packets.add(playerRemove);
packets.add(getAddPacket());
}

return packets.toArray(new DataPacket[0]);
}

private AddEntityPacket getAddPacket() {
AddEntityPacket pk = new AddEntityPacket();
pk.id = "minecraft:armor_stand";
pk.entityUniqueId = this.entityId;
pk.entityRuntimeId = this.entityId;
pk.x = (float) this.x;
pk.y = (float) this.y - 0.75f;
pk.z = (float) this.z;
pk.metadata = this.metadata;
return pk;
}

private RemoveEntityPacket getRemovePacket() {
RemoveEntityPacket pk = new RemoveEntityPacket();
pk.eid = this.entityId;
return pk;
}
}

0 comments on commit ab419d1

Please sign in to comment.