#Text above head [JAVA]

65 messages · Page 1 of 1 (latest)

severe oar
#

I'm making a plugin with the feature to display a player's chat messages above their head, but i only want one chat message displayed at a time. I have a HashMap that links a player to one armor stand, but multiple may exist at the same time regardless of the checks i have in place. I think it has something to do with these lines (INSIDE A FUNCTION WHICH IS CALLED ON PLAYERCHATEVENT).

        if (playerArmorStand.containsKey(p)) {
            ArmorStand existingStand = playerArmorStand.get(p);
            existingStand.remove();
            playerArmorStand.remove(p);
        }

        // Set variables to be used
        Location loc = p.getLocation();
        ArmorStand chat = p.getWorld().spawn(loc, ArmorStand.class);
        World world = p.getWorld();

        // Associate a specific armor stand with the player
        playerArmorStand.put(p, chat);
chilly pulsar
#

just create 1 armor stand and rename it rather than creating a new one each time

severe oar
#

and that check just doesnt work for some reason

chilly pulsar
#
@EventHandler
    fun onChat(event: PlayerChatEvent) {
        val player = event.player
        val stand = armorStands[player]
        if (stand != null) {
            stand.customName = event.message
        } else {
            val created = player.world.spawn(player.location.add(0.0, 0.5, 0.0), ArmorStand::class.java)
            created.setGravity(false)
            created.isVisible = false
            created.customName = event.message
            created.isCustomNameVisible = true
            created.isInvulnerable = true
            armorStands[player] = created
        }
    }

this code worked fine for me.just convert it to java

severe oar
#

ill put the whole class here

#

i tried to implement a similar solution, bt didnt work

#
public class MessageHead {

    private final server plugin;

    public MessageHead(server plugin) {
        this.plugin = plugin;
    }

    public final Map<Player, Queue<String>> map = new HashMap<>();

    public final Map<Player, ArmorStand> playerArmorStand = new HashMap<>();

    public final Map<Player, Boolean> armorStandExists = new HashMap<>();

    public void messageDisplay(Player p, String m) {

        if (armorStandExists.get(p) != null) {
            return;
        }

        // Set variables to be used
        Location loc = p.getLocation();
        World world = p.getWorld();
        ArmorStand chat = world.spawn(loc, ArmorStand.class);

        // Associate a specific armor stand with the player
        playerArmorStand.put(p, chat);
        armorStandExists.put(p, true);

        // Set armor stand properties
        chat.setVisible(false);
        chat.setGravity(false);

        // Final shenanigans to make it work in the runnable
        final String[] chatMessage = {""};
        final int[] finalI = new int[1];

        // Repeating task instead of a loop, so I can add delay
        new BukkitRunnable() {
            @Override
            public void run() {

                // Display message character by character
                chatMessage[0] = chatMessage[0] + m.charAt(finalI[0]);
                chat.setCustomName(chatMessage[0]);
                chat.setCustomNameVisible(true);

                // Play sound as if player has a voice
                Location newloc = p.getLocation();
                world.playSound(newloc, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 0.5F, 1);

                // Teleport armor stand to player
                messageTeleport(p);

                // When loop is finished
                if (finalI[0] + 1 >= m.length()) {

                    // Get rid of display
                    messageFade(chat, p);
                    cancel();
                }

                finalI[0]++;
            }
        }.runTaskTimer(plugin, 0, 1);
    }

    public void messageQueue(Player p, String m){

        // Create temp queue
        Queue<String> messageQ = new LinkedList<>();

        // If map doesn't have anything, add it
        if (!map.containsKey(p)){
            map.put(p, messageQ);
        }
        map.get(p).offer(m);
    }

    public void showNextMessage(Player p){

        Queue<String> messageQueue = map.get(p);
        if (messageQueue != null && !messageQueue.isEmpty()){
            String nextMessage = messageQueue.poll();
            messageDisplay(p, nextMessage);
        }
    }

    public void messageTeleport(Player p) {
        if (!(map.get(p) == null)){
            ArmorStand a = playerArmorStand.get(p);
            a.teleport(p);
        }
    }

    public void messageFade(ArmorStand a, Player p){
        BukkitTask balls = new BukkitRunnable(){
            @Override
            public void run(){
                messageTeleport(p);
            }
        }.runTaskTimer(plugin, 1, 1);
        new BukkitRunnable(){
            @Override
            public void run(){
                balls.cancel();
                a.remove();
                playerArmorStand.remove(p);
                armorStandExists.replace(p, null);
                showNextMessage(p);
            }
        }.runTaskLater(plugin, 80L);
    }
}
#

ignore bukkittask balls

#

was very tired last night

chilly pulsar
#

so is the issue just that there are multiple armor stands for a player getting created?

severe oar
#

on each chat message, yes

#

i want it to skip creation until the previous finishes displaying

#

but it doesnt want to do that

#

perhaps i can do stuff with the persistent data container

chilly pulsar
#

try adding debug messages before and after each condition to see what part of the code it is reaching and where it stops

severe oar
#

set it to 1 when there exists an armor stand, and

#

ok

severe oar
#

so basically the maps are local variables

#

even though i declare ttthem outside the functions

#

if only i could store a queue inside tthe persistent data container

crystal carbon
#

i saw a plugin like what you tryna make on spigotmcc, best of luck makin this

severe oar
#

thanks

#

it's almost done i just don't know how to access a persistent queue

#

perhaps if i created a queue for the player when they joined

severe oar
#

GOT IT TO WORK

#

i love the static modifier

crystal carbon
# severe oar

feels like the text could be more dynamic but sick 😄

severe oar
#

wdym

crystal carbon
#

what i mean for dynamic is like behind the text its like gray dark ish

#

idk how you would exactly do it but ik it's possible

severe oar
#

i mean it's just vanilla nametag stuff with armor stands

crystal carbon
# severe oar

is this gonna be a public plugin or is it private?

severe oar
#

private

crystal carbon
#

aw

severe oar
#

i mean i could make a seperate version that is public

crystal carbon
#

😄

severe oar
#

it also includes the ability to change your "voice" (sound effect used when a character is displayed) and voice pitch

#

im working on a reputation system for my plugin though

severe oar
#

player hits another player. if victim dies shortly after (like 30 seconds), the attacker's reputation value goes down

#

was thinking to color peoples' text based on their reputation value

#

so if they were really "bad players", their text would be red

#

and if they were really good, it would be light blue or something

crystal carbon
severe oar
#

how would be easily abused

crystal carbon
#

trust me

severe oar
#

well its mostly to pinpoint people who often kill others compared to their playtime

#

they would get reputation points over time played, so if they killed people a lot they would have a relatively low reputation

crystal carbon
#

reputation system has never worked out for anything in mc tbh

severe oar
#

was also thinking about it being a ratio to like (((player kills * 20) + (damage to players))/2)/(time played in hrs/30)

crystal carbon
# severe oar what do you mean

i remember i heard about how there was a plugin in older days of mc where if u got banned 3 times on ANY server with the plugin you would get perm banned on any with the plugin, so after a group of griefers got the 3 strikes they just made there own server server 3x and banned whoever banned them, a decent example of a reputation system not working

severe oar
#

dang

#

that crazy but not really what im aiming for

#

more to allow the players to distinguish between friendlies and non-friendlies

#

though there could be someone that just runs around and breaks stuff and places blocks to grief that wouldn't be marked as unfriendly

#

and people would often try to kill them

#

so they would lose rep

#

hmmm

#

i have an idea

#

dont think its ever been done before