-
Posts
297 -
Joined
-
Last visited
-
Days Won
3
Posts posted by Alpvax
-
-
My only suggestion would be YAML.
I know it isn't perfect, I would rather have the braces there to show the hierachy, but it allows comments in addition to everything JSON allows (as far as I am aware).
Alternatively someone could write a custom format (probably JSON-based) that allows comments. It could even be as simple as a custom JSON parser.
-
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.
-
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?
-
Sorry for a bit of a Necro, but I am now having the same issue. Could you please tell me how you solved it
-
The scale and the abuse are two reasons why I haven't written an implementation. However I like the idea, and would use it if it was implemented.
-
I think the plan from here would be to create the API then submit a PR. The issue with a standalone API is that no-one hears about it for a long time.
-
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
-
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
-
I did not even think of that, I was just basing it purely off the vanilla code, but you have a good point. maybe it should just be a new method in Item, that way it could be called for any "visible" Item.
-
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;
-
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
-
Sorry to bother you, but how would you define the path? from which directory? or just using the package structure?
-
1
-
-
Solved it, My .zip was actually a .rar with the extension changed
-
Hate to revive a dead thread, this is marked as solved, however I don't see a solution. Could somebody point out whatever I'm missing, as I have the same problem.
-
Everywhere I look, people are referencing the "forge folder" which forge folder would this be? I cannot see any forge folder, only ".gradle", "build", "eclipse", "gradle" and "src". (of course, .gradle doesn't show up in Eclipse)
-
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; }
-
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
-
public void onLogin(LivingSpawnEvent event) { if(event.entity instanceof EntityPlayer)
Spawn is for mobs, actually...
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())
-
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
-
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
[1.10.12] Disable swappinp hand (F key) on item
in Modder Support
Posted
Would a better solution not be to do an item.isvalidforslot check of some description? That way the player couldn't click the item into the offhand slot either.