Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generalised entities and added new hologram type #109

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package de.oliver.fancyholograms.api.data;

import de.oliver.fancyholograms.api.hologram.HologramType;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;

public class DroppedItemHologramData extends HologramData {

public static final ItemStack DEFAULT_ITEM = new ItemStack(Material.APPLE);

private ItemStack item = DEFAULT_ITEM;

/**
* @param name Name of hologram
* @param location Location of hologram
* Default values are already set
*/
public DroppedItemHologramData(String name, Location location) {
super(name, HologramType.DROPPED_ITEM, location);
}

public ItemStack getItemStack() {
return item;
}

public DroppedItemHologramData setItemStack(ItemStack item) {
this.item = item;
setHasChanges(true);
return this;
}

@Override
public void read(ConfigurationSection section, String name) {
super.read(section, name);
item = section.getItemStack("item", DEFAULT_ITEM);
}

@Override
public void write(ConfigurationSection section, String name) {
super.write(section, name);
section.set("item", item);
}

@Override
public DroppedItemHologramData copy(String name) {
DroppedItemHologramData droppedItemHologramData = new DroppedItemHologramData(name, getLocation());
droppedItemHologramData
.setItemStack(this.getItemStack())
.setVisibilityDistance(this.getVisibilityDistance())
.setVisibility(this.getVisibility())
.setPersistent(this.isPersistent())
.setLinkedNpcName(this.getLinkedNpcName());

return droppedItemHologramData;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.World;
import org.bukkit.entity.Display;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -53,13 +53,12 @@ public String getName() {
}

/**
* Returns the Display entity of this Hologram object.
* The entity is not registered in the world or server.
* Only use this method if you know what you're doing.
*
* @return the Display entity of this Hologram object
* @return the Hologram's entity object
*/
public abstract @Nullable Display getDisplayEntity();
public abstract @Nullable Entity getEntity();

protected abstract void create();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
public enum HologramType {
TEXT(Arrays.asList("background", "textshadow", "textalignment", "seethrough", "setline", "removeline", "addline", "insertbefore", "insertafter", "updatetextinterval")),
ITEM(List.of("item")),
BLOCK(List.of("block"));
BLOCK(List.of("block")),
DROPPED_ITEM(List.of("item"));

private final List<String> commands;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
import net.minecraft.util.Brightness;
import net.minecraft.world.entity.Display;
import net.minecraft.world.entity.Display.TextDisplay;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
Expand All @@ -39,15 +41,15 @@
public final class Hologram1_19_4 extends Hologram {

@Nullable
private Display display;
private Entity entity;

public Hologram1_19_4(@NotNull final HologramData data) {
super(data);
}

@Override
public @Nullable org.bukkit.entity.Display getDisplayEntity() {
return display != null ? (org.bukkit.entity.Display) display.getBukkitEntity() : null;
public @Nullable org.bukkit.entity.Entity getEntity() {
return entity != null ? entity.getBukkitEntity() : null;
}

@Override
Expand All @@ -60,29 +62,32 @@ public void create() {
ServerLevel world = ((CraftWorld) location.getWorld()).getHandle();

switch (data.getType()) {
case TEXT -> this.display = new Display.TextDisplay(EntityType.TEXT_DISPLAY, world);
case BLOCK -> this.display = new Display.BlockDisplay(EntityType.BLOCK_DISPLAY, world);
case ITEM -> this.display = new Display.ItemDisplay(EntityType.ITEM_DISPLAY, world);
case TEXT -> this.entity = new Display.TextDisplay(EntityType.TEXT_DISPLAY, world);
case BLOCK -> this.entity = new Display.BlockDisplay(EntityType.BLOCK_DISPLAY, world);
case ITEM -> this.entity = new Display.ItemDisplay(EntityType.ITEM_DISPLAY, world);
case DROPPED_ITEM -> {
this.entity = new ItemEntity(EntityType.ITEM, world);
this.entity.setNoGravity(true);
}
}

final var DATA_INTERPOLATION_DURATION_ID = ReflectionUtils.getStaticValue(Display.class, MappingKeys1_19_4.DATA_INTERPOLATION_DURATION_ID.getMapping());
display.getEntityData().set((EntityDataAccessor<Integer>) DATA_INTERPOLATION_DURATION_ID, 1);

final var DATA_INTERPOLATION_START_DELTA_TICKS_ID = ReflectionUtils.getStaticValue(Display.class, MappingKeys1_19_4.DATA_INTERPOLATION_START_DELTA_TICKS_ID.getMapping());
display.getEntityData().set((EntityDataAccessor<Integer>) DATA_INTERPOLATION_START_DELTA_TICKS_ID, 0);
if (this.entity instanceof Display display) {
display.setInterpolationDuration(1);
display.setInterpolationDelay(0);
}

update();
}

@Override
public void delete() {
this.display = null;
this.entity = null;
}

@Override
public void update() {
final var display = this.display;
if (display == null) {
final var entity = this.entity;
if (entity == null) {
return; // doesn't exist, nothing to update
}

Expand All @@ -91,26 +96,26 @@ public void update() {
if (!location.isWorldLoaded()) {
return;
} else {
display.setPosRaw(location.x(), location.y(), location.z());
display.setYRot(location.getYaw());
display.setXRot(location.getPitch());
entity.setPosRaw(location.x(), location.y(), location.z());
entity.setYRot(location.getYaw());
entity.setXRot(location.getPitch());
}

if (display instanceof TextDisplay textDisplay && data instanceof TextHologramData textData) {
if (entity instanceof TextDisplay textDisplay && data instanceof TextHologramData textData) {
// line width
final var DATA_LINE_WIDTH_ID = ReflectionUtils.getStaticValue(TextDisplay.class, MappingKeys1_19_4.DATA_LINE_WIDTH_ID.getMapping());
display.getEntityData().set((EntityDataAccessor<Integer>) DATA_LINE_WIDTH_ID, Hologram.LINE_WIDTH);
entity.getEntityData().set((EntityDataAccessor<Integer>) DATA_LINE_WIDTH_ID, Hologram.LINE_WIDTH);

// background
final var DATA_BACKGROUND_COLOR_ID = ReflectionUtils.getStaticValue(TextDisplay.class, MappingKeys1_19_4.DATA_BACKGROUND_COLOR_ID.getMapping());

final var background = textData.getBackground();
if (background == null) {
display.getEntityData().set((EntityDataAccessor<Integer>) DATA_BACKGROUND_COLOR_ID, TextDisplay.INITIAL_BACKGROUND);
entity.getEntityData().set((EntityDataAccessor<Integer>) DATA_BACKGROUND_COLOR_ID, TextDisplay.INITIAL_BACKGROUND);
} else if (background == Hologram.TRANSPARENT) {
display.getEntityData().set((EntityDataAccessor<Integer>) DATA_BACKGROUND_COLOR_ID, 0);
entity.getEntityData().set((EntityDataAccessor<Integer>) DATA_BACKGROUND_COLOR_ID, 0);
} else {
display.getEntityData().set((EntityDataAccessor<Integer>) DATA_BACKGROUND_COLOR_ID, background.asARGB());
entity.getEntityData().set((EntityDataAccessor<Integer>) DATA_BACKGROUND_COLOR_ID, background.asARGB());
}

// text shadow
Expand Down Expand Up @@ -140,16 +145,19 @@ public void update() {
textDisplay.setFlags((byte) (textDisplay.getFlags() & ~TextDisplay.FLAG_ALIGN_RIGHT));
}

} else if (display instanceof Display.ItemDisplay itemDisplay && data instanceof ItemHologramData itemData) {
} else if (entity instanceof Display.ItemDisplay itemDisplay && data instanceof ItemHologramData itemData) {
// item
itemDisplay.setItemStack(ItemStack.fromBukkitCopy(itemData.getItemStack()));

} else if (display instanceof Display.BlockDisplay blockDisplay && data instanceof BlockHologramData blockData) {
} else if (entity instanceof Display.BlockDisplay blockDisplay && data instanceof BlockHologramData blockData) {
Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.of("minecraft:" + blockData.getBlock().name().toLowerCase(), ':'));
blockDisplay.setBlockState(block.defaultBlockState());
} else if (entity instanceof ItemEntity item && data instanceof DroppedItemHologramData itemData) {
// item
item.setItem(ItemStack.fromBukkitCopy(itemData.getItemStack()));
}

if (data instanceof DisplayHologramData displayData) {
if (entity instanceof Display display && data instanceof DisplayHologramData displayData) {
// billboard data
display.setBillboardConstraints(switch (displayData.getBillboard()) {
case FIXED -> Display.BillboardConstraints.FIXED;
Expand Down Expand Up @@ -184,12 +192,12 @@ public boolean show(@NotNull final Player player) {
return false;
}

if (this.display == null) {
if (this.entity == null) {
create(); // try to create it if it doesn't exist every time
}

final var display = this.display;
if (display == null) {
final var entity = this.entity;
if (entity == null) {
return false; // could not be created, nothing to show
}

Expand All @@ -206,7 +214,7 @@ public boolean show(@NotNull final Player player) {
// return false;
// }

serverPlayer.connection.send(new ClientboundAddEntityPacket(display));
serverPlayer.connection.send(new ClientboundAddEntityPacket(entity));
this.viewers.add(player.getUniqueId());
refreshHologram(player);

Expand All @@ -219,12 +227,12 @@ public boolean hide(@NotNull final Player player) {
return false;
}

final var display = this.display;
if (display == null) {
final var entity = this.entity;
if (entity == null) {
return false; // doesn't exist, nothing to hide
}

((CraftPlayer) player).getHandle().connection.send(new ClientboundRemoveEntitiesPacket(display.getId()));
((CraftPlayer) player).getHandle().connection.send(new ClientboundRemoveEntitiesPacket(entity.getId()));

this.viewers.remove(player.getUniqueId());
return true;
Expand All @@ -233,29 +241,29 @@ public boolean hide(@NotNull final Player player) {

@Override
public void refresh(@NotNull final Player player) {
final var display = this.display;
if (display == null) {
final var entity = this.entity;
if (entity == null) {
return; // doesn't exist, nothing to refresh
}

if (!isViewer(player)) {
return;
}

((CraftPlayer) player).getHandle().connection.send(new ClientboundTeleportEntityPacket(display));
((CraftPlayer) player).getHandle().connection.send(new ClientboundTeleportEntityPacket(entity));

if (display instanceof TextDisplay textDisplay) {
if (entity instanceof TextDisplay textDisplay) {
textDisplay.setText(PaperAdventure.asVanilla(getShownText(player)));
}

final var values = new ArrayList<DataValue<?>>();

//noinspection unchecked
for (final var item : ((Int2ObjectMap<DataItem<?>>) getValue(display.getEntityData(), "e")).values()) {
for (final var item : ((Int2ObjectMap<DataItem<?>>) getValue(entity.getEntityData(), "e")).values()) {
values.add(item.value());
}

((CraftPlayer) player).getHandle().connection.send(new ClientboundSetEntityDataPacket(display.getId(), values));
((CraftPlayer) player).getHandle().connection.send(new ClientboundSetEntityDataPacket(entity.getId(), values));
}

}
Loading