Отображение убийств на экране

Отображение убийств на экране 1.0.0

Нет прав для скачивания
Версия(и) Minecraft
1.12.2
Писал был мод, который выводит убийства что-то типа в стиле кс, но так как он уже не нужен, то выкладываю, может кому будет интересен или полезен код/принцип.

Выводит на экран в стиле "Убийца-Оружие(которым убили)-Жертва", если килов несколько подряд, то стакает один под другим, вплоть до указаного кол-ва. Через некоторое время пропадает.

Совместим с сервером.

Результат работы:
Тесты
lviCtuh.png

lDLFAwi.png

Java:
package com.thunder.pvpinfomod;

import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.GlStateManager.DestFactor;
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.DamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.living.LivingDeathEvent;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent.Phase;
import net.minecraftforge.fml.common.gameevent.TickEvent.PlayerTickEvent;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraftforge.fml.relauncher.Side;

import static java.lang.System.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.logging.log4j.core.appender.db.jpa.converter.StackTraceElementAttributeConverter;
import org.lwjgl.opengl.GL11;
import org.w3c.dom.css.Counter;

import com.thunder.pvpinfomod.PVPInfo.PVPInfoOverlay.PvPContainer;

import io.netty.buffer.ByteBuf;

@Mod(modid = PVPInfo.MOD_ID, name = PVPInfo.MOD_NAME, version = PVPInfo.VERSION)
public class PVPInfo {

    public static final String MOD_NAME = "PvP Info Mod";
    public static final String MOD_ID = "pvpinfomod";
    public static final String VERSION = "1.0.0";

    @Mod.Instance(PVPInfo.MOD_ID)
    public static PVPInfo INSTANCE;

    @EventHandler
    public void preInit(FMLPreInitializationEvent event) {
        PVPNetwork.init();
    }

    @EventHandler
    public void init(FMLInitializationEvent event) {
        MinecraftForge.EVENT_BUS.register(this);
        if(FMLCommonHandler.instance().getEffectiveSide().isClient())
            MinecraftForge.EVENT_BUS.register(new PVPInfoOverlay());
    }

    public static class PVPNetwork {
    
        public static SimpleNetworkWrapper network;
    
        public static void init() {
            network = NetworkRegistry.INSTANCE.newSimpleChannel(PVPInfo.MOD_ID);
            network.registerMessage(PvPPacket.Handler.class, PvPPacket.class, 0, Side.CLIENT);
        }
    }

    //client
    public static class PvPPacket implements IMessage {
    
        public NBTTagCompound nbtTag;
        public ItemStack stack;
    
        public PvPPacket() {}
    
        public PvPPacket(NBTTagCompound nbtTag, ItemStack stack) {
            this.nbtTag = nbtTag;
            this.stack = stack;
        }

        @Override
        public void fromBytes(ByteBuf buf) {
            nbtTag = ByteBufUtils.readTag(buf);
            stack = ByteBufUtils.readItemStack(buf);
        }

        @Override
        public void toBytes(ByteBuf buf) {
            ByteBufUtils.writeTag(buf, nbtTag);
            ByteBufUtils.writeItemStack(buf, stack);
        }

        public static class Handler implements IMessageHandler<PvPPacket, IMessage> {
        
            @Override
            public IMessage onMessage(PvPPacket message, MessageContext ctx) {
                EntityPlayerSP player = Minecraft.getMinecraft().player;
                if(player!= null){
                    NBTTagCompound tagCompound = message.nbtTag;
                    ItemStack weapon = message.stack;
                    PVPInfoOverlay.tasks.add(0, new PvPContainer(tagCompound.getString("killer"), tagCompound.getString("victim"), weapon));
                    PVPInfoOverlay.canShow = true;
                    PVPInfoOverlay.ticker = 0;
                }   
                return null;
            }
        }
    }

    //server
    @SubscribeEvent
    public void onDeath(LivingDeathEvent event){
        EntityLivingBase victim = event.getEntityLiving();
        DamageSource killer = event.getSource();
        if(victim != null && victim instanceof EntityPlayer && killer.getTrueSource() instanceof EntityPlayer){
            EntityPlayer vPlayer = (EntityPlayer)victim;
            EntityPlayer kPlayer = (EntityPlayer)killer.getTrueSource();
            ItemStack weapon = kPlayer.getHeldItem(kPlayer.getActiveHand());
            PVPNetwork.network.sendToAll(new PvPPacket(createPvPInfo(kPlayer.getDisplayNameString(), vPlayer.getDisplayNameString()),
                    weapon.isEmpty() ? new ItemStack(Items.WOODEN_SWORD) : weapon));
        }
    }

    //client
    public static class PVPInfoOverlay extends Gui {
    
        public static final int TASK_SIZE = 4;
        public static final int X_OFFSET = 4;
        public static final int Y_OFFSET = 10;
        public static ArrayList<PvPContainer> tasks = new ArrayList<PVPInfoOverlay.PvPContainer>(TASK_SIZE);
        public static Minecraft mc = Minecraft.getMinecraft();
    
        public static final double SCALE = 0.5d;
    
        public static int ticker;
        public static boolean canShow;
        public static final int TIME_TO_SHOW = 400;
                    
        @SubscribeEvent
        public void renderOverlay(RenderGameOverlayEvent event) {
            if (event.isCancelable() || event.getType() != RenderGameOverlayEvent.ElementType.EXPERIENCE)
                return;
            int start_x = 5;
            int start_y = 5;     
            if(tasks.size() > TASK_SIZE) {
                tasks.remove(TASK_SIZE);
                tasks.trimToSize();
            } 
            if(canShow){
                if(ticker < TIME_TO_SHOW){
                    for(PvPContainer task : tasks){
                        if(task != null){
                            String killer = task.killer;
                            String victim = task.victim;
                            int sWidth = (int)((mc.fontRenderer.getStringWidth(killer) + X_OFFSET) * SCALE);
                            int gWidth = sWidth + 10 + (int)((mc.fontRenderer.getStringWidth(victim) + X_OFFSET * 2) * SCALE);
                            GlStateManager.pushMatrix();
                            GlStateManager.scale(SCALE, SCALE, SCALE);
                            //draw font
                            drawRect((int)((start_x - 2) / SCALE), (int)((start_y - 2) / SCALE), (int)(gWidth / SCALE) + X_OFFSET, (int)(start_y / SCALE) + Y_OFFSET + 2, Integer.MIN_VALUE);
                            //draw text and icon
                            mc.fontRenderer.drawString(killer, (int)(start_x / SCALE), (int)(start_y / SCALE), 0xd80f0f);
                            renderStack(task.weapon, (int)((start_x + sWidth) / SCALE), (int)(start_y / SCALE) - 4);
                            mc.fontRenderer.drawString(victim, (int)((start_x + sWidth + 6 + X_OFFSET) / SCALE), (int)(start_y / SCALE), 0x27c615);
                            GlStateManager.popMatrix();
                            start_y += Y_OFFSET;
                        }
                    }
                }else{
                    ticker = 0;
                    canShow = false;
                    tasks.clear();
                }
            }
        }
    
        @SubscribeEvent
        public void onTick(PlayerTickEvent event){
            if(event.phase == Phase.END){
                PVPInfoOverlay.ticker++;
                if(PVPInfoOverlay.ticker > PVPInfoOverlay.TIME_TO_SHOW) PVPInfoOverlay.ticker = 0;
            }
        }

        public void renderStack(ItemStack stack, int x, int y){
            RenderHelper.enableGUIStandardItemLighting();
            mc.getRenderItem().renderItemAndEffectIntoGUI(stack, x, y);
            RenderHelper.disableStandardItemLighting();
        }
    
        public static class PvPContainer {
        
            public String killer;
            public String victim;
            public ItemStack weapon;
        
            public PvPContainer(String killer, String victim, ItemStack weapon){
                this.killer = killer;
                this.victim = victim;
                this.weapon = weapon;
            }
        }
    }

    public static NBTTagCompound createPvPInfo(String killer, String victim){
        NBTTagCompound pTag = new NBTTagCompound();
        pTag.setString("killer", killer);
        pTag.setString("victim", victim);
        return pTag;
    }
}

Пока пришла в голову только такая идея, как реализовать. Возможно, есть что лучше. Тут все довольно простенько и лениво)
Автор
Eifel
Скачивания
59
Просмотры
2,055
Первый выпуск
Обновление
Оценка
4.50 звёзд 2 оценок

Другие ресурсы пользователя Eifel

Последние рецензии

Можно было бы при смерти писать в центре кто убил и чем
Eifel
Eifel
Если надо в центре, то можно сделать в центре самому)
Хорошо выглядит.
Сверху