Jump to content

Alpvax

Members
  • Posts

    297
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by Alpvax

  1. When I have done this previously, I had to shrink the collision box fractionally, as the collision wouldn't register unless the entity was inside the block space. I am not sure if this has been changed or if it is still the case. I am also unsure how that would work with the new model system, as the last time I did it was around 1.3, so I could easily have the textures remain the full block, but the collision fractionally smaller.

  2. So I will be instantiating some of my classes from NBTTagCompounds as well as from other methods, and I need to be able to pass in a variable number of variable-type arguments. I could either pass them in as a Map<String,Object> or pass in an NBTTagCompound, and just keep a reference to the nbt inside my instance.

    Obviously the latter would be easier, and is what entities and itemstacks do, but what is the additional overhead vs a HashMap?

  3. The "not all may want to support it" argument is pointless, you could say exactly the same thing about forge itself. If they don't want to support it they won't, but what reason would they have not to? The macerator dictionary would be useful for a single (or maybe a couple of) blocks from a few mods. A heat dictionary would allow for better control and differentiation between light level and heat for melting blocks like ice.

    It would also simplify mechanics such as factorizations furnace heater. And where is the logic in a standard torch being hot enough to heat a crucible but a furnace heater isn'?  This would become a compatibility layer, which makes forge the perfect place for it

  4. I would imagine any calculation would be done when the heat level is checked, so if no mod uses it no processing is done. Not quite the same as light. However if it was implemented alongside light it wpuld allow for a better implementation of ice melting. (Based on heat level as opposed to light level) and wouldnt need to constantly check heat level

  5. Within World.getClosestVunerablePlayer there is an invisibility check (if mobs can't see you they won't attack) which also calls EntityPlayer.getArmourVisibility:

        /**
         * When searching for vulnerable players, if a player is invisible, the return value of this is the chance of seeing
         * them anyway.
         */
        public float getArmorVisibility()
        {
            int i = 0;
            ItemStack[] aitemstack = this.inventory.armorInventory;
            int j = aitemstack.length;
    
            for (int k = 0; k < j; ++k)
            {
                ItemStack itemstack = aitemstack[k];
    
                if (itemstack != null)
                {
                    ++i;
                }
            }
    
            return (float)i / (float)this.inventory.armorInventory.length;
        }
    

    I think there should be some check for the armour being invisible (mmmPowersuits comes to mind), or semi-visible.

     

        /**
         * When searching for vulnerable players, if a player is invisible, the return value of this is the chance of seeing
         * them anyway.
         */
        public float getArmorVisibility()
        {
            float f = 0;
            ItemStack[] aitemstack = this.inventory.armorInventory;
            int j = aitemstack.length;
    
            for (int k = 0; k < j; ++k)
            {
                ItemStack itemstack = aitemstack[k];
    
                if (itemstack != null)
                {
                     //new function that returns the opacity of the ItemStack. default implementation would return 1.0F (i.e. fully opaque).
                    f += itemstack.getItem().getVisibility(itemstack);
                }
            }
    
            return f / (float)this.inventory.armorInventory.length;
        }
    

    I would have suggested adding this check to ItemArmor, but due to the fact that any item can be armour, it would have to be a general method.

    Alternatively it could be part of a new interface IArmor, and the isValidArmor method would return if the item was an instanceof IArmor

    public interface IArmor
    {
    public ItemArmor.ArmorMaterial getArmorMaterial(); //various other armor-related methods could be moved across
    public float getArmorOpacity(ItemStack stack);
    }
    

    and the check would become:

    Item item = itemstack.getItem();
    f += item instanceof IArmor ? ((IArmor)item).getArmorOpacity(itemstack) : 1.0F;
    

  6. Heat would work similarly to light, it would decrease depending on distance travelled, and certain blocks would decrease it more than others (based on hardness and material) the numbers need to be worked on, and there would have to be some agreement between modders, but the idea itself would be useful

  7. You don't need a container if you don't want inventory slots.

     

    Thanks for the confirmation, I didn't think so.

     

    GUI class (will be re-written at some point, its a tad messy, but I know it works as it appears when I kill myself (EntityJoinWorldEvent launches it))

     

    package alpvax.classmod.client;
    
    import net.minecraft.client.Minecraft;
    import net.minecraft.client.gui.FontRenderer;
    import net.minecraft.client.gui.Gui;
    import net.minecraft.client.gui.GuiButton;
    import net.minecraft.client.gui.GuiScreen;
    
    import org.lwjgl.opengl.GL11;
    
    import alpvax.classmod.core.ClassMod;
    import alpvax.classmod.core.ClassUtil;
    import alpvax.classmod.network.packet.ClassSelectPacket;
    import alpvax.classmod.playerclass.PlayerClass;
    import cpw.mods.fml.common.network.PacketDispatcher;
    
    import static alpvax.classmod.core.ClassMod.selectGUIMaxC;
    import static alpvax.classmod.core.ClassMod.selectGUIMaxR;
    
    public class GuiClassSelect extends GuiScreen
    {
    private static int xPadding = 10;
    private static int yPadding = 10;
    private int page;
    private int maxPages = 1;
    
    /**
         * Adds the buttons (and other controls) to the screen in question.
         */
    @Override
        public void initGui()
        {
            this.buttonList.clear();
            int i = PlayerClass.allowedClasses.size();
            if (i > selectGUIMaxC * selectGUIMaxR)
            {
                buttonList.add(new GuiButton(0, width / 2 - (62 + xPadding), height / 2 + 58, 20, 20, "<"));
                buttonList.add(new GuiButton(1, width / 2 + (62 + xPadding), height / 2 + 58, 20, 20, ">"));
                maxPages = (int)Math.floor(i / selectGUIMaxC * selectGUIMaxR);
            }
            for(int i1 = 0; i1 < maxPages; i1++)
            {
            int j = getNumRows();
        	int startY = height / 2 - (j * 96 + (j - 1) * yPadding) / 2;
            for(int j1 = 0; j1 < j; j1++)
            {
            	int k = getNumForRow(j1);
            	int startX = width / 2 - (k * 62 + (k - 1) * xPadding) / 2;
            	for(int k1 = 0; k1 < k; k1++)
            	{
            		makeClassButton(i1, j1, k1, startX, startY);
            	}
            }
            }
        }
    
    /**
         * Draws the screen and all the components in it.
         */
    @Override
        public void drawScreen(int mouseX, int mouseY, float partialTicks)
        {
    	this.drawDefaultBackground();
            for (int var4 = 0; var4 < buttonList.size(); ++var4)
            {
            	if(this.buttonList.get(var4) instanceof GuiButton)
            	{
                GuiButton var5 = (GuiButton)this.buttonList.get(var4);
                var5.drawButton(this.mc, mouseX, mouseY);
            	}
            	else
            	{
            		GuiClassButton var5 = (GuiClassButton)this.buttonList.get(var4);
                    var5.undraw();
            	}
            }
            int i = getNumRows();
        	int startY = height / 2 - (i * 96 + (i - 1) * yPadding) / 2;
            GL11.glPushMatrix();
            this.drawCenteredString(this.fontRenderer, "Select your class", this.width / 2, startY - yPadding, 16777215);
            GL11.glPopMatrix();
            for(int i1 = 0; i1 < i; i1++)
            {
            	int j = getNumForRow(i1);
            	int startX = width / 2 - (j * 62 + (j - 1) * xPadding) / 2;
            	for(int j1 = 0; j1 < j; j1++)
            	{
                    GuiClassButton var5 = (GuiClassButton)this.buttonList.get(page * selectGUIMaxC * selectGUIMaxR + i1 * selectGUIMaxC + j1);// + maxPages > 1 ? 2 : 0);
                    var5.draw(this.mc, mouseX, mouseY);
            	}
            }
        }
    
    /**
         * Called when the mouse is clicked.
         */
    @Override
        protected void mouseClicked(int par1, int par2, int par3)
        {
            if (par3 == 0)
            {
                for (int var4 = 0; var4 < this.buttonList.size(); ++var4)
                {
                	if(buttonList.get(var4) instanceof GuiButton)
                	{
                    GuiButton var5 = (GuiButton)this.buttonList.get(var4);
    
                    if (var5.mousePressed(this.mc, par1, par2))
                    {
                        this.mc.sndManager.playSoundFX("random.click", 1.0F, 1.0F);
                        this.actionPerformed(var5);
                    }
                	}
                	else
                	{
                		GuiClassButton var5 = (GuiClassButton)this.buttonList.get(var4);
    
                    if(var5.mousePressed(this.mc, par1, par2))
                    {
                    	PacketDispatcher.sendPacketToServer(new ClassSelectPacket(mc.thePlayer, var5.playerclass).makePacket());
                        //PlayerClass.setPlayerClass(mc.thePlayer, var5.playerclass);
                        System.out.println(var5.playerclass);
                        mc.setIngameFocus();
            	        //PlayerClass.startPowerDelay();
                    }
                	}
                }
            }
        }
    
    /**
         * Fired when a control is clicked. This is the equivalent of ActionListener.actionPerformed(ActionEvent e).
         */
    @Override
        protected void actionPerformed(GuiButton par1GuiButton)
        {
            switch (par1GuiButton.id)
            {
                case 0:
                    page = Math.max(page - 1, 0);
                    break;
                case 1:
                    page = Math.min(page + 1, maxPages);
                    break;
            }
            initGui();
        }
    
    private int getNumForPage()
    {
    	return Math.min(PlayerClass.allowedClasses.size() - page * selectGUIMaxC * selectGUIMaxR, selectGUIMaxC * selectGUIMaxR);
    }
    
    private int getNumRows()
    {
    	return (int)Math.ceil((float)getNumForPage() / (float)selectGUIMaxC);
    }
    
    private int getNumForRow(int row)
    {
    	return Math.min(getNumForPage() - row * selectGUIMaxC, selectGUIMaxC);
    }
    
    private void makeClassButton(int currentPage, int row, int column, int startX, int startY)
    {
    	int i = startX + (62 + xPadding) * column;
    	int j = startY + (96 + yPadding) * row;
    	PlayerClass playerclass = PlayerClass.getPlayerClass(PlayerClass.allowedClasses.get(currentPage * selectGUIMaxC * selectGUIMaxR + row * selectGUIMaxC + column));
    	buttonList.add(new GuiClassButton(i, j, playerclass));
    }
    
    public class GuiClassButton extends Gui
    {
    	/** Button width in pixels */
        protected int width = 62;
    
        /** Button height in pixels */
        protected int height = 96;
    
        /** The x position of this control. */
        public int xPosition;
    
        /** The y position of this control. */
        public int yPosition;
        
        /** Is not drawn */
        private boolean hidden = true;
        
        /** The y position of this control. */
        public PlayerClass playerclass;
    
    	public GuiClassButton(int par1, int par2, PlayerClass par3PlayerClass)
    	{
    		xPosition = par1;
    		yPosition = par2;
    		playerclass = par3PlayerClass;
    	}
    
        /**
         * Returns 0 if the button is disabled, 1 if the mouse is NOT hovering over this button and 2 if it IS hovering over
         * this button.
         */
        protected int getHoverState(boolean par1)
        {
            return par1 ? 2 : 1;
        }
        
        /**
         * Returns true if the mouse has been pressed on this control. Equivalent of MouseListener.mousePressed(MouseEvent
         * e).
         */
        public boolean mousePressed(Minecraft mc, int mouseX, int mouseY)
        {
            return !hidden && mouseX >= this.xPosition && mouseY >= this.yPosition && mouseX < this.xPosition + this.width && mouseY < this.yPosition + this.height;
        }
        
        public void draw(Minecraft mc, int mouseX, int mouseY)
        {
        	hidden = false;
            mc.getTextureManager().bindTexture(playerclass.getIcon());
                drawTexturedModalRect(xPosition + 8, yPosition + 12, 0, 0, 46, 73);
        	mc.getTextureManager().bindTexture(ClassUtil.classGUIMain);
            drawTexturedModalRect(xPosition, yPosition, 0, 0, 62, 96);
                boolean flag = mouseX >= this.xPosition && mouseY >= this.yPosition && mouseX < this.xPosition + this.width && mouseY < this.yPosition + this.height;
            if(flag)
            {
                drawTexturedModalRect(xPosition - 10, yPosition - 10, 62, 0, 86, 118);
            }
            FontRenderer fr = mc.fontRenderer;
            String s = playerclass.getDisplayName();
            fr.drawStringWithShadow(s, xPosition + width / 2 - fr.getStringWidth(s) / 2, yPosition + 85, 16777215);
        }
        
        public void undraw()
        {
        	hidden = true;
        }
    }
    }
    

     

     

    And my proxy/ GUIHandler methods

     

    @Override
    public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
    {
    	if(ID == ClassUtil.classGUIID) return new GuiClassSelect();
    	return null;
    }
    
    @Override
    public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
    {
    	return null;
    }

     

  8.  

    The result of the button pressed within the GUI changes the value, or sending a command. As of yet I don't think the value is ever changed because I haven't finished my packet handler.

    Which means it should always open at this point ?

    I guess there is something wrong in your gui handling code, then.

     

    Correct, it should always open the first time a player logs into a new world / server.

    My server-side gui element is returned as null, is that what is causing the problem? Do I have to make a blank container as the gui consists of nothing but buttons, which send a packet to the server when clicked, and close the GUI

  9. public void onLogin(LivingSpawnEvent event)
    {
    	if(event.entity instanceof EntityPlayer)
    

    Spawn is for mobs, actually...:P

    Explains why adding this event handler didn't make the print statements appear twice, thanks for the explanation.

     

    if(!ep.hasPlayerClass())
    

    When is this value set to true ?

    The result of the button pressed within the GUI changes the value, or sending a command. As of yet I don't think the value is ever changed because I haven't finished my packet handler.

     

     

    I think the easiest way to do this is to create a class which implements IConnectionHandler and use this function:

     

    public void playerLoggedIn(Player player, NetHandler netHandler, INetworkManager manager)

     

    Thanks, will try that. Do I need to register said class somewhere? Such as in the @Mod class?

     

    EDIT: Never mind, found it. (NetworkRegistry.registerConnectionHandler())

  10. I have tried to open my custom GUI on logging in/ spawning.

    I know the code works, as the GUI opens when I respawn, but not on initial login.

     

    EventHandler:

     

    
    @SideOnly(Side.CLIENT)
    @ForgeSubscribe
    public void onLogin(EntityJoinWorldEvent event)
    {
    	if(event.entity instanceof EntityPlayer)
    	{
    		EntityPlayer player = (EntityPlayer)event.entity;
    		ExtendedPlayer ep = ExtendedPlayer.get(player);
    		ep.loadProxyData();
    		System.out.println(player);
    		System.out.println(ExtendedPlayer.get(player).getPlayerClass());
    		if(!ep.hasPlayerClass())
    		{
    			player.openGui(ClassMod.instance, ClassUtil.classGUIID, player.worldObj, (int)player.posX, (int)player.posY, (int)player.posZ);
    		}
    	}
    }
    
    @SideOnly(Side.CLIENT)
    @ForgeSubscribe
    public void onLogin(LivingSpawnEvent event)
    {
    	if(event.entity instanceof EntityPlayer)
    	{
    		EntityPlayer player = (EntityPlayer)event.entity;
    		ExtendedPlayer ep = ExtendedPlayer.get(player);
    		ep.loadProxyData();
    		System.out.println(player);
    		System.out.println(ExtendedPlayer.get(player).getPlayerClass());
    		if(!ep.hasPlayerClass())
    		{
    			player.openGui(ClassMod.instance, ClassUtil.classGUIID, player.worldObj, (int)player.posX, (int)player.posY, (int)player.posZ);
    		}
    	}
    }

     

     

    Eclipse Output:

     

    2013-10-23 08:49:18 [iNFO] [Minecraft-Server] Player933 joined the game
    2013-10-23 08:49:18 [iNFO] [sTDOUT] EntityPlayerMP['Player933'/413, l='New World', x=-538.50, y=64.00, z=-275.50]
    2013-10-23 08:49:18 [iNFO] [sTDOUT] null
    2013-10-23 08:49:18 [iNFO] [sTDOUT] Setting up custom skins
    2013-10-23 08:49:18 [iNFO] [sTDOUT] EntityClientPlayerMP['Player933'/414, l='MpServer', x=8.50, y=66.62, z=8.50]
    2013-10-23 08:49:18 [iNFO] [sTDOUT] null

     

  11. There is an event for any entity other than a player joining the world, why can we not have an event for the player joining? for example this could be used to open a gui upon joining a server for the first time

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.