Jump to content

hugo_the_dwarf

Members
  • Posts

    334
  • Joined

  • Last visited

Everything posted by hugo_the_dwarf

  1. Player inventory uses IContainer as well so "when" a change happens in a container for a player's inventory, check to see what was going on. I haven't looked much into container listeners but I know a few people have played with them. Mainly so far for capabilities.
  2. I've gotten it to the point where I'm happy, If the item is in another container. There is no way to to see what the items have "Unidentified..." but if you move them into your inventory and hover over they will update and show their colors. I'm wondering would it be possible to ask the forge team to let itemStacks hold a reference of their "current" inventory if not I think I'll look into some more events for when loot chests generate loot (so chests in dark places will have strong items) and maybe look into any container open events to try to get a packet sync system for external inventories I've also updated my repo for anyone that wants to see how I did it. htd.rot.managers.PacketManager htd.rot.events.EventItemLogic htd.rot.comms.packets.capabilities.CapAttributeItemRequestPacket htd.rot.comms.packets.capabilities.CapAttributeItemResponsePacket It's a bit messy for now since the player has like 3 inventories inside the InventoryPlayer (Main, Offhand, Armor) Thanks for the help Choonster
  3. PlayerEvent.BreakSpeed Get the entity from the event which would be the player get the inventory of the player get the currentItem from the mainInventory of the InventoryPlayer .... Profit?? PS event also contains the block too.
  4. Is there a supplied "This is the GUI image (actual file), and this is what it looks like in game" is the Image File saved as a 256X256 (or multiple of)
  5. Thank you very much, I must have just over complicated the whole darn thing. Thankfully I have a check to go through the equipped items and tally up the stats + class stats and send them off to the player. So even tho they all show up as "Unidentified" I can still see the stats in action via my GUI Now it's getting this update request response system going.
  6. Hmm... I made some tweaks and removed the "item" from the Capability as since the item is just the INSTANCE no point holding it as the ItemStack would hold more power.. The tweaks did nothing which isn't surpising. However this code doesn't seem to display what I intend, which is at the very bottom of this: @SubscribeEvent public void onItemToolTipUpdate(ItemTooltipEvent e) { if (e.getItemStack().hasCapability(CapAttribute.CAPABILITY, null)) { CapAttributeData cap = e.getItemStack().getCapability(CapAttribute.CAPABILITY, null); if (cap != null) { if (!cap.needsUpdate) { int ITEMS_PER_LINE = 2; int currentLineItems = 0; String lineItems = ""; for (int index = 0; index < cap.attributes.length; index++) { if (currentLineItems < ITEMS_PER_LINE) { if (cap.attributes[index] != 0) { lineItems += HTDDataInfo.ATTRIBUTE_TAGS[index] + ": " + cap.attributes[index]; currentLineItems++; } } else { e.getToolTip().add(lineItems); lineItems = ""; currentLineItems = 0; } } if (currentLineItems > 0) e.getToolTip().add(lineItems); lineItems = ""; currentLineItems = 0; for (int index = 0; index < cap.stats.length; index++) { if (currentLineItems < ITEMS_PER_LINE) { if (cap.stats[index] != 0) { lineItems += HTDDataInfo.STAT_TAGS[index] + ": " + cap.stats[index]; currentLineItems++; } } else { e.getToolTip().add(lineItems); lineItems = ""; currentLineItems = 0; } } if (currentLineItems > 0) e.getToolTip().add(lineItems); } } else { e.getToolTip().add("Unidentified..."); } } } If there is a Capability on the ItemStack but since the capability on the client would be a fresh make of the Capability the Boolean needsUpdate will be true, triggering the code to say "This item is unidentified" to show in the toolTip at the bottom. This is also where I'd start putting the "search through inventories, find matching stack, return Inventory and Slot Id send to server. ask it for the updated capability, update client. And since this event runs "per tick" more or less once the data gets there it will be rendered in the toolTip. So there is a great chance I have messed up somewhere.
  7. So ran into a different issue. For attaching capabilities I was using: @SubscribeEvent public void onAddCapabilitiesItemStack(AttachCapabilitiesEvent<ItemStack> e) wondering why nothing was getting a capability looked at the documentation and i'm supposed to use <Item> changed it, and some console.outs are telling me things are now being set. However I don't think my provider is working correctly. Anyone have an example of attaching Capabilities to Items? because I've noticed only ItemStack has getCapability() [spoiler=Capability] package htd.rot.capability.attribute; import java.util.concurrent.Callable; import net.minecraft.nbt.NBTBase; import net.minecraft.util.EnumFacing; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.CapabilityManager; public class CapAttribute { @CapabilityInject(CapAttributeData.class) public static Capability<CapAttributeData> CAPABILITY = null; public static void register() { CapabilityManager.INSTANCE.register(CapAttributeData.class, new StorageHelper(), new DefaultInstanceFactory()); } public static class StorageHelper implements Capability.IStorage<CapAttributeData> { @Override public NBTBase writeNBT(Capability<CapAttributeData> capability, CapAttributeData instance, EnumFacing side) { return instance.writeData(); } @Override public void readNBT(Capability<CapAttributeData> capability, CapAttributeData instance, EnumFacing side, NBTBase nbt) { instance.readData(nbt); } } public static class DefaultInstanceFactory implements Callable<CapAttributeData> { @Override public CapAttributeData call() throws Exception { return new CapAttributeData(); } } } [spoiler=CapabilityData] package htd.rot.capability.attribute; import java.util.Random; import htd.rot.capability.playerextra.CapPlayerExtra; import htd.rot.capability.playerextra.CapPlayerExtraData; import htd.rot.libs.HTDDataInfo; import htd.rot.managers.PlayerCPTypeManager; import net.minecraft.entity.EntityLivingBase; import net.minecraft.item.Item; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.math.BlockPos; public class CapAttributeData { private EntityLivingBase entity; private Item item; public int[] attributes = new int[HTDDataInfo.ATTRIBUTE_TAGS.length]; public float[] stats = new float[HTDDataInfo.STAT_TAGS.length]; public boolean isExhausted = false, needsUpdate = true; public CapAttributeData() { initData(); } public EntityLivingBase getEntity() { return entity; } public void setEntity(EntityLivingBase entity) { this.entity = entity; } public Item getItem() { return item; } public void setItem(Item item) { this.item = item; } private void initData() { for (int index = 0; index < attributes.length; index++) { attributes[index] = HTDDataInfo.attributes[index]; } for (int index = 0; index < stats.length; index++) { stats[index] = HTDDataInfo.stats[index]; } } // Stamina public boolean needsStam() { return stats[HTDDataInfo.STAM] < HTDDataInfo.MAX_STAM_MANA; } public boolean consumeStam(float cost) { float adjustedCost = (cost * getAdjustedStamCostPercent(cost)); if (stats[HTDDataInfo.STAM] - adjustedCost >= 0) { stats[HTDDataInfo.STAM] -= adjustedCost; return true; } return false; } public void regenStam() { float amount = (stats[HTDDataInfo.VITALITY] * 0.0578f) + (stats[HTDDataInfo.BONUS_STAM_REGEN] * 0.20f); addStam(amount); } public void addStam(float amount) { stats[HTDDataInfo.STAM] += (HTDDataInfo.MAX_STAM_MANA * (((getAdjustedMaxStam() + amount) / getAdjustedMaxStam()) - 1f)); if (stats[HTDDataInfo.STAM] > HTDDataInfo.MAX_STAM_MANA) stats[HTDDataInfo.STAM] = HTDDataInfo.MAX_STAM_MANA; } public float getAdjustedMaxStam() { CapPlayerExtraData playerExtra = entity.getCapability(CapPlayerExtra.CAPABILITY, null); float maxStam = HTDDataInfo.MAX_STAM_MANA; if (playerExtra != null && playerExtra.getCurrentClass() != -1) maxStam += (PlayerCPTypeManager.classes[playerExtra.getCurrentClass()].stamPerVitStat * attributes[HTDDataInfo.VITALITY]) + PlayerCPTypeManager.classes[playerExtra.getCurrentClass()].stats[HTDDataInfo.BONUS_STAM]; else // Mobs maxStam += (5 * attributes[HTDDataInfo.VITALITY]); maxStam += stats[HTDDataInfo.BONUS_STAM]; return maxStam; } public float getAdjustedCurrentStam() { return getAdjustedMaxStam() * (stats[HTDDataInfo.STAM] / HTDDataInfo.MAX_STAM_MANA); } public float getAdjustedStamCostPercent(float cost) { return 1f - ((getAdjustedMaxStam() - cost) / getAdjustedMaxStam()); } // Mana public boolean needsMana() { return stats[HTDDataInfo.MANA] < HTDDataInfo.MAX_STAM_MANA; } public boolean consumeMana(float cost) { float adjustedCost = (cost * getAdjustedManaCostPercent(cost)); if (stats[HTDDataInfo.MANA] - adjustedCost >= 0) { stats[HTDDataInfo.MANA] -= adjustedCost; return true; } return false; } public void regenMana() { float amount = (stats[HTDDataInfo.INTELLIGENCE] * 0.0578f) + (stats[HTDDataInfo.BONUS_MANA_REGEN] * 0.20f); addMana(amount); } public void addMana(float amount) { stats[HTDDataInfo.MANA] += (HTDDataInfo.MAX_STAM_MANA * (((getAdjustedMaxMana() + amount) / getAdjustedMaxMana()) - 1f)); if (stats[HTDDataInfo.MANA] > HTDDataInfo.MAX_STAM_MANA) stats[HTDDataInfo.MANA] = HTDDataInfo.MAX_STAM_MANA; } public float getAdjustedMaxMana() { CapPlayerExtraData playerExtra = entity.getCapability(CapPlayerExtra.CAPABILITY, null); float maxMana = HTDDataInfo.MAX_STAM_MANA; if (playerExtra != null && playerExtra.getCurrentClass() != -1) maxMana += (PlayerCPTypeManager.classes[playerExtra.getCurrentClass()].manaPerIntStat * attributes[HTDDataInfo.INTELLIGENCE]) + PlayerCPTypeManager.classes[playerExtra.getCurrentClass()].stats[HTDDataInfo.BONUS_MANA]; else // Mobs maxMana += (5 * attributes[HTDDataInfo.INTELLIGENCE]); maxMana += stats[HTDDataInfo.BONUS_MANA]; return maxMana; } public float getAdjustedCurrentMana() { return getAdjustedMaxMana() * (stats[HTDDataInfo.MANA] / HTDDataInfo.MAX_STAM_MANA); } public float getAdjustedManaCostPercent(float cost) { return 1f - ((getAdjustedMaxMana() - cost) / getAdjustedMaxMana()); } // Health public float getAdjustedMaxHealth() { CapPlayerExtraData playerExtra = entity.getCapability(CapPlayerExtra.CAPABILITY, null); float maxHP = entity.getMaxHealth() * HTDDataInfo.BASE_UPSCALE; if (playerExtra != null && playerExtra.getCurrentClass() != -1) maxHP += (PlayerCPTypeManager.classes[playerExtra.getCurrentClass()].hpPerVit * attributes[HTDDataInfo.VITALITY]) + PlayerCPTypeManager.classes[playerExtra.getCurrentClass()].stats[HTDDataInfo.BONUS_HP]; else // Mobs maxHP += (5 * attributes[HTDDataInfo.VITALITY]); maxHP += stats[HTDDataInfo.BONUS_HP]; return maxHP; } public float getAdjustedCurrentHealth() { return getAdjustedMaxHealth() * (entity.getHealth() / entity.getMaxHealth()); } public float getAdjustedDamagePercent(float damage) { return 1f - ((getAdjustedMaxHealth() - damage) / getAdjustedMaxHealth()); } public void rollStats() { int[] attrs = new int[attributes.length]; int lowerHeight = 62; int upperHeight = 100; int yHeight = (int) entity.posY; int heightBonus = 0; int sunlessDepth = 0; if (!entity.worldObj.canBlockSeeSky(new BlockPos(entity.posX, entity.posY, entity.posZ))) { for (int yOffset = 1; yOffset <= 50; yOffset++) { if (!entity.worldObj.canBlockSeeSky(new BlockPos(entity.posX, entity.posY + yOffset, entity.posZ))) sunlessDepth++; else break; } } if (yHeight < lowerHeight) heightBonus = (int) ((yHeight - lowerHeight) * 2.85f); else if (yHeight > upperHeight) heightBonus = yHeight - upperHeight; heightBonus = heightBonus < 0 ? heightBonus * -1 : heightBonus; int baseBonus = 5 + sunlessDepth; Random rand = new Random(); for (int index = 0; index < attributes.length; index++) { attrs[index] = (baseBonus + (heightBonus <= 0 ? 0 : rand.nextInt(heightBonus)) + (sunlessDepth <= 0 ? 0 : rand.nextInt(sunlessDepth))); } attrs[HTDDataInfo.LIFE_STEAL] = 0; attrs[HTDDataInfo.MANA_STEAL] = 0; updateAttributes(attrs); } public void rollItemStats() { int[] attrs = new int[attributes.length]; int baseBonus = 5; Random rand = new Random(); for (int index = 0; index < attributes.length; index++) { attrs[index] = (baseBonus + rand.nextInt(12)); } attrs[HTDDataInfo.LIFE_STEAL] = 0; attrs[HTDDataInfo.MANA_STEAL] = 0; updateAttributes(attrs); } public NBTBase writeData() { NBTTagCompound tag = new NBTTagCompound(); for (int index = 0; index < attributes.length; index++) { tag.setInteger(HTDDataInfo.ATTRIBUTE_TAGS[index].trim().toLowerCase(), attributes[index]); } for (int index = 0; index < stats.length; index++) { tag.setFloat(HTDDataInfo.STAT_TAGS[index].trim().toLowerCase(), stats[index]); } return tag; } public void readData(NBTBase nbt) { NBTTagCompound tag = (NBTTagCompound) nbt; for (int index = 0; index < attributes.length; index++) { attributes[index] = tag.getInteger(HTDDataInfo.ATTRIBUTE_TAGS[index].trim().toLowerCase()); } for (int index = 0; index < stats.length; index++) { stats[index] = tag.getFloat(HTDDataInfo.STAT_TAGS[index].trim().toLowerCase()); } } public Object[] compressData() { Object[] data = new Object[attributes.length + stats.length]; int dataIndex = 0; for (int index = 0; index < attributes.length; index++) { data[dataIndex++] = attributes[index]; } for (int index = 0; index < stats.length; index++) { data[dataIndex++] = stats[index]; } return data; } public void decompressData(Object[] data) { int dataIndex = 0; for (int index = 0; index < attributes.length; index++) { attributes[index] = (int) data[dataIndex++]; } for (int index = 0; index < stats.length; index++) { stats[index] = (float) data[dataIndex++]; } updateAttributes(attributes); } public void updateAttributes(int[] attributes) { int[] pulledAttributes = attributes; for (int index = 0; index < this.attributes.length; index++) { pulledAttributes[index] = pulledAttributes[index] > HTDDataInfo.ATTRIBUTE_MAX_LIMIT ? HTDDataInfo.ATTRIBUTE_MAX_LIMIT : pulledAttributes[index]; pulledAttributes[index] = pulledAttributes[index] < (HTDDataInfo.ATTRIBUTE_MAX_LIMIT * -1) ? (HTDDataInfo.ATTRIBUTE_MAX_LIMIT * -1) : pulledAttributes[index]; } pulledAttributes[HTDDataInfo.MAX_DAMAGE] = pulledAttributes[HTDDataInfo.MAX_DAMAGE] < pulledAttributes[HTDDataInfo.MIN_DAMAGE] ? pulledAttributes[HTDDataInfo.MIN_DAMAGE] : pulledAttributes[HTDDataInfo.MAX_DAMAGE]; this.attributes = pulledAttributes; } } [spoiler=CapabilityProvider] package htd.rot.capability.attribute; import htd.rot.Rot; import net.minecraft.entity.EntityLivingBase; import net.minecraft.item.Item; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.capabilities.ICapabilitySerializable; public class CapAttributeProvider implements ICapabilityProvider, ICapabilitySerializable<NBTTagCompound> { public static final ResourceLocation KEY = new ResourceLocation(Rot.MODID, "htd_attributes"); private CapAttributeData INSTANCE = new CapAttributeData(); public CapAttributeProvider(EntityLivingBase entity) { INSTANCE.setEntity(entity); } public CapAttributeProvider(Item item) { INSTANCE.setItem(item); } @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { return capability == CapAttribute.CAPABILITY; } @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) { if (capability == CapAttribute.CAPABILITY) return (T) INSTANCE; return null; } @Override public NBTTagCompound serializeNBT() { return (NBTTagCompound) CapAttribute.CAPABILITY.writeNBT(INSTANCE, null); } @Override public void deserializeNBT(NBTTagCompound nbt) { CapAttribute.CAPABILITY.readNBT(INSTANCE, null, nbt); } } [spoiler=Event] @SubscribeEvent public void onAddCapabilitiesItemStack(AttachCapabilitiesEvent<Item> e) { if (canHaveAttributes(e.getObject())) { Console.out().println(e.getObject().getClass().getName()); e.addCapability(CapAttributeProvider.KEY, new CapAttributeProvider(e.getObject())); } } public static boolean canHaveAttributes(Item item) { if ((item instanceof ItemTool || item instanceof ItemSword || item instanceof ItemBow || item instanceof ItemArmor || item instanceof ItemShield)) return true; return false; } EDIT: Updated my REPO found in my sig, incase I forgot a file that you'd want to look at
  8. So far is the "AttachCapabilitiesEvent<>" the only way to put capabilities on? Only wondering because I was thinking of adding "Unique" look items (weapons) that are not from the standard ItemTool/ItemSword era IE Baked_Potato. However I don't want to put the capability on ALL items just certain types. And in this case a Bake_Potato does not fall into that list. Now this item will be created during a mobs death so created by me dynamically, is there anyway to attach a capability to an item even if it doesn't make it through the check for the event? Item created Event checks Fails Item Instance pass Is from unique item list Attach Capability? apply unique stats apply custom name and enchantment (to give the shiny effect) I'm trying to stay away from adding new blocks and items if I can, as I'd like my mod to be something like the Infernal Mobs mod where it doesn't add new content just new mechanics and can adapt to any other mod. And also reuse all Vanilla items/blocks if I can. Idk the impact of adding a capability to ALL items. If there is no impact at all then I will go ahead and just slap it on, then check if it's the correct item type or a unique to roll stats EDIT: Ran into an issue with my idea for the request/response. The toolTipEvent doesn't supply a "Item current index" and I don't have any other ID's to use to try to toss to the server asking for "get Cap from ItemStack in player inventory at INDEX" then return it (with index) and update it on the client. How would I go about getting what item the player is looking at/mouse is hovering over? Was thinking of using a loop to go through the players inventory and match the itemstack 1=1 but I think if I had say two Iron Swords and I was looking at the sword deeper in the inventory the one that was higher up on the list would be returned instead.
  9. Referenced Libraries -> forgeSrc-[Version Number]-[build].jar -> net.minecraftforge.event net.minecraftforge.event.brewing net.minecraftforge.event.entity.item net.minecraftforge.event.entity.living net.minecraftforge.event.entity.minecart net.minecraftforge.event.entity.player net.minecraftforge.event.terraingen net.minecraftforge.event.world net.minecraftforge.fml.common.event EDIT: net.minecraftforge.fml.common.gameevent You're able to look at everything that is in the game and forge in there, so you can find anything in there.
  10. Thanks that's the info I needed. Of course I will have more Qs later as I go, but this answers one that was glaring at me as I was going. Thanks again.
  11. Ah Crud, just remembered, When a mob is killed. I had random loot drop based on how tough it was, likewise the toughness of the mob determined the stats of the loot dropped (if valid equipment type) Now the mob stats are easy to get (the loot table) it's having the Items get their stats rolled based on the dead mob's power. Does the "Attach Capability" event trigger as soon as "New ItemStack" is called? Likewise I do this for crafting too (ItemCraftedEvent) so players have a chance to at least make some gear that has some ok stats so they can start the grind. Q: When does an ItemStack get it's Capability Attached? Right as it is created in code via New ItemStack?
  12. Hmm.. Ok so I updated the event to what you suggested, no issues, good. I might have to stick with ye olde NBT read and write that I had before, However Once something for ItemStacks becomes a little easier I'll be converting ASAP. Going by the thread the asker had to do quite a bit of tinkering just to get the attach and removal of listeners. Since the Cap is still server-side and most of my mechanics are server-side (events) would be fine, only issue is allowing the player to read what is added to the item (client-side) as their stats only take place once the player is holding (main or offhand) or wearing the piece. But would be nice to see if the stats are harmful before putting on/holding The reads mainly happened every few seconds before or when hovering over an item "ItemTooltipEvent" which I guess if I really wanted to, I could just have it check during that event to update the cap if the default cap had a "boolean needsUpdate = true" to ask the server the stacks real cap. Would that work? (Using a request/reponse packet system in the ItemTooltipEvent) As when wearing gear or holding something, it's the server that tallies up all the values, and just fires a packet off (if it needs to) to update the client for any GUIs I use
  13. Currently so far I've been dealing with Entities and I seem to have that handled fairly well. I have an Attribute Capability that can be on Entities and items (I can easily modify the provider and constructors to take and save an ItemStack as well as an Entity, easy) My question is will I have to create update packets for ItemStack Capabilities or will it be handled like NBT is (more or less synced automatically by MC all ready) If I need to create these update events, when should I have them "query" the server for their information? Player Update event (check inventory, see if needs to be updated, ask server, get response) Also the current way I'm using it: @SubscribeEvent public void onAddCapabilities(AttachCapabilitiesEvent.Entity e) { if (canHaveAttributes(e.getEntity())) { EntityLivingBase ent = (EntityLivingBase)e.getEntity(); if (ent instanceof EntityPlayer) e.addCapability(CapPlayerExtraProvider.KEY, new CapPlayerExtraProvider(ent)); e.addCapability(CapAttributeProvider.KEY, new CapAttributeProvider(ent)); } } says the subEvent is deprecated, what is the new/upcoming correct way to use this?
  14. OMG I'm just an idiot Was switching from an old way how I did things to a new way that I figure would be "easier" to manage the reading/writing of packet buffers and NBT Where I have 3 vars 2 of them are arrays One set to be a named Index One Array for Name/Keys Final Array for stored Data So in the given packet classes I have "props.currentClass" which is my index... It should have been "props.playerInfo[props.currentClass]" So now i'm changing the indexes to FINAL and making them all CAPS, and will be creating some getter/setter methods EDIT: Thanks for the help, but I still have the question of the New Runable(SendTo(message,player)) for my request packets to send the response. or any packet for that matter.
  15. That looks like it would return the damage of the PlayerEntity which fists are weak, and would assume 1.0f damage to be correct for a player to do. Try getting Player.Inventory.HeldItem(); and checking the damage of the ITEM rather the PLAYER however most "damage" comes from the material the ITEM is made from.
  16. [spoiler=CapPlayerExtraProvider] package htd.rot.capability.playerextra; import htd.rot.Rot; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.capabilities.ICapabilitySerializable; public class CapPlayerExtraProvider implements ICapabilityProvider, ICapabilitySerializable<NBTTagCompound> { public static final ResourceLocation KEY = new ResourceLocation(Rot.MODID, "htd_playerextra"); private CapPlayerExtraData INSTANCE = new CapPlayerExtraData(); public CapPlayerExtraProvider(EntityLivingBase entity) { INSTANCE.setEntity(entity); } @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { return capability == CapPlayerExtra.CAPABILITY; } @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) { if (capability == CapPlayerExtra.CAPABILITY)return (T)INSTANCE; return null; } @Override public NBTTagCompound serializeNBT() { return (NBTTagCompound)CapPlayerExtra.CAPABILITY.writeNBT(INSTANCE, null); } @Override public void deserializeNBT(NBTTagCompound nbt) { CapPlayerExtra.CAPABILITY.readNBT(INSTANCE, null, nbt); } } I know strangely if I have the Capability randomly assign values to values, and have a full data sync (so server and client are out of sync with different Random.nextInt() values) the client will be updated through the code in the playerTick and livingUpdate events with a simple just fire it off from the server to client (dataChanged() method). So would I have to rewrite some of my packet handlers to appear like this? @Override public IMessage onMessage(ClassGUIPacket message, MessageContext ctx) { // Open the gui on the server so we can actually do stuff. EntityPlayer player = ctx.getServerHandler().playerEntity; ctx.getServerHandler(). playerEntity. getServerWorld(). addScheduledTask( new Runnable() { public void run() { player.openGui(Rot.INSTANCE, GuiHandler.CLASS_GUI, player.worldObj, (int) player.posX, (int) player.posY, (int) player.posZ); } }); return null; } } Of course if I have a request/repsonse system would I add inside the runnable (task) a "PacketManager.INSTANCE.SendTo()" and just leave my returns as NULL?
  17. I'm working with a system of: Press Keybinding to open "Player Class Menu" Select Class and/or Profession in GUI Press save Fire packet from client to server check to see if player has a class, no class allow free class change. Else check to see if they have enough gold to change. Send Response Packet to update client (server > client) Where it apparently is failing is I'm guessing the saving portion within the "requestPacket"(client > server) As the changes never stay, or save. [spoiler=gui code] package htd.rot.client.gui; import org.lwjgl.opengl.GL11; import htd.rot.Rot; import htd.rot.capability.attribute.CapAttribute; import htd.rot.capability.attribute.CapAttributeData; import htd.rot.capability.playerextra.CapPlayerExtra; import htd.rot.capability.playerextra.CapPlayerExtraData; import htd.rot.comms.packets.ClassRequestPacket; import htd.rot.comms.packets.ProfessionRequestPacket; import htd.rot.managers.PacketManager; import htd.rot.managers.PlayerCPTypeManager; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.ResourceLocation; public class GuiClassSelection extends GuiContainer { public static final ResourceLocation texture = new ResourceLocation(Rot.MODID.toLowerCase(), "textures/gui/rotGui.png"); private EntityPlayer player; private int pad = 4; private int ch = 20; private int selectedClass = -1; private int selectedProfession = -1; public GuiClassSelection(EntityPlayer player) { super(new ContainerNull()); this.player = player; this.xSize = 176; this.ySize = 166; this.selectedClass = player.getCapability(CapPlayerExtra.CAPABILITY, null).currentClass; this.selectedProfession = player.getCapability(CapPlayerExtra.CAPABILITY, null).currentProfession; } /** Button Clicks **/ @Override protected void actionPerformed(GuiButton button) { switch (button.id) { case 0: // Class Forward this.selectedClass++; this.selectedClass = this.selectedClass == PlayerCPTypeManager.classes.length ? 0 : this.selectedClass; break; case 1: // Class Back this.selectedClass--; this.selectedClass = this.selectedClass < 0 ? PlayerCPTypeManager.classes.length - 1 : this.selectedClass; break; case 2: // Change Class PacketManager.INSTANCE.sendToServer(new ClassRequestPacket(selectedClass)); break; case 3: // Refresh Class PacketManager.INSTANCE.sendToServer(new ClassRequestPacket(0)); break; case 4: // Profession Forward this.selectedProfession++; this.selectedProfession = this.selectedProfession == PlayerCPTypeManager.professions.length ? 0 : this.selectedProfession; break; case 5: // Profession Back this.selectedProfession--; this.selectedProfession = this.selectedProfession < 0 ? PlayerCPTypeManager.professions.length - 1 : this.selectedProfession; break; case 6: // Change Profession PacketManager.INSTANCE.sendToServer(new ProfessionRequestPacket(selectedProfession)); break; case 7:// Refresh Profession PacketManager.INSTANCE.sendToServer(new ProfessionRequestPacket(0)); break; } } @Override protected void drawGuiContainerBackgroundLayer(float f, int i, int j) { /* * TextureManager manager = Minecraft.getMinecraft().renderEngine; * manager.bindTexture(manager.getResourceLocation(1)); //RENDER ITEMS * drawTexturedModelRectFromIcon(300, 300, * RotItems.itemGunpowderInfuser.getIconFromDamage(0), 16, 16); */ GL11.glColor4f(1F, 1F, 1F, 1F); Minecraft.getMinecraft().renderEngine.bindTexture(texture); drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize); this.buttonList.clear(); // Start with main control buttons CapPlayerExtraData playerExtra = player.getCapability(CapPlayerExtra.CAPABILITY, null); CapAttributeData attrs = player.getCapability(CapAttribute.CAPABILITY, null); int x1 = this.guiLeft + this.pad; int x2 = (this.guiLeft + this.xSize) - (8 + this.pad); int x3 = (x2 + x1) / 2; int textY = this.guiTop + this.pad; int textX = (this.guiLeft + this.xSize) + pad; this.buttonList.add(new GuiClassSelectionButton(0, x2, this.guiTop + this.pad, "", 1)); this.buttonList.add(new GuiClassSelectionButton(4, x2, this.guiTop + this.pad + (8 * 2), "", 1)); this.drawString(this.fontRendererObj, this.selectedClass != -1 ? PlayerCPTypeManager.classes[this.selectedClass].className : "None", x3, this.guiTop + this.pad + 5, 0xddeeee); this.drawString(this.fontRendererObj, this.selectedProfession != -1 ? PlayerCPTypeManager.professions[this.selectedProfession].professionName : "None", x3, this.guiTop + this.pad + 20, 0xddeeee); this.buttonList.add(new GuiClassSelectionButton(1, x2 - 8, this.guiTop + this.pad, "", 0)); this.buttonList.add(new GuiClassSelectionButton(2, x2 - 8, this.guiTop + this.pad + 8, "", 2)); this.buttonList.add(new GuiClassSelectionButton(3, x2, this.guiTop + this.pad + 8, "", 3)); this.buttonList.add(new GuiClassSelectionButton(5, x2 - 8, this.guiTop + this.pad + (8 * 2), "", 0)); this.buttonList.add(new GuiClassSelectionButton(6, x2 - 8, this.guiTop + this.pad + (8 * 3), "", 2)); this.buttonList.add(new GuiClassSelectionButton(7, x2, this.guiTop + this.pad + (8 * 3), "", 3)); this.drawString(this.fontRendererObj, "Current Class:", textX, textY, 0xdbdd15); textY += 15; this.drawString(this.fontRendererObj, playerExtra.currentClass == -1 ? "None" : PlayerCPTypeManager.classes[playerExtra.currentClass].className, textX, textY, 0xdbdd15); textY += 15; for (int index = 0; index < attrs.attributes.length;index++) { this.drawString(this.fontRendererObj, attrs.ATTRIBUTE_TAGS[index] + ": " + attrs.attributes[index], textX, textY, attrs.attributes[index] == 0 ? 0xFFFFFF : attrs.attributes[index] > 0 ? 0x00ff42 : 0xff0c00); textY += 15; } this.drawString(this.fontRendererObj, "Current Profession:", textX, textY, 0xdbdd15); textY += 15; this.drawString(this.fontRendererObj, playerExtra.currentProfession == -1 ? "None" : PlayerCPTypeManager.professions[playerExtra.currentClass].professionName, textX, textY, 0xdbdd15); // Visual information on location /* * this.drawString(fontRendererObj, "X: "+(xOffset+te.xCoord)+ * " offSet: "+xOffset, (startLeft + ((gridSizeX * 2) * cw)) + cw * 5, * (startTop + (gridSizeZ * ch) + 4) - ch, 0xFFFFFF); * this.drawString(fontRendererObj, "Y: "+(yOffset+te.yCoord)+ * " offSet: "+yOffset, (startLeft + ((gridSizeX * 2) * cw)) + cw * 5, * (startTop + (gridSizeZ * ch) + 4), 0xFFFFFF); * this.drawString(fontRendererObj, "Z: "+(zOffset+te.zCoord)+ * " offSet: "+zOffset, (startLeft + ((gridSizeX * 2) * cw)) + cw * 5, * (startTop + (gridSizeZ * ch) + 4) + ch, 0xFFFFFF); */ } /** Keyboard Clicks **/ @Override protected void keyTyped(char par1, int par2) { if ((par2 == 1) || (par2 == this.mc.gameSettings.keyBindInventory.getKeyCode())) { this.mc.thePlayer.closeScreen(); } } } [spoiler=request packet] package htd.rot.comms.packets; import htd.rot.capability.playerextra.CapPlayerExtra; import htd.rot.capability.playerextra.CapPlayerExtraData; import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayer; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; public class ClassRequestPacket implements IMessage { public static class ClassRequestPacketHandler implements IMessageHandler<ClassRequestPacket, IMessage> { @Override public IMessage onMessage(ClassRequestPacket message, MessageContext ctx) { final int goldCost = 500; if (message.classID == -1) { return null; } EntityPlayer player = ctx.getServerHandler().playerEntity; CapPlayerExtraData props = player.getCapability(CapPlayerExtra.CAPABILITY, null); if (props.currentClass == -1) { props.currentClass = message.classID; return new ClassResponsePacket(props.currentClass,props.gold); } else { if (props.playerInfo[props.gold] >= goldCost) { props.playerInfo[props.gold] -= goldCost; props.currentClass = message.classID; return new ClassResponsePacket(props.currentClass,props.gold); } } return null; } } public int classID; public ClassRequestPacket() { } public ClassRequestPacket(int className) { this.classID = className; } @Override public void fromBytes(ByteBuf buf) { this.classID = buf.readInt(); } @Override public void toBytes(ByteBuf buf) { buf.writeInt(this.classID); } } [spoiler=response packet] package htd.rot.comms.packets; import htd.rot.capability.playerextra.CapPlayerExtra; import htd.rot.capability.playerextra.CapPlayerExtraData; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; public class ClassResponsePacket implements IMessage { public static class ClassResponsePacketHandler implements IMessageHandler<ClassResponsePacket, IMessage> { @Override public IMessage onMessage(ClassResponsePacket message, MessageContext ctx) { EntityPlayer player = Minecraft.getMinecraft().thePlayer; player.getCapability(CapPlayerExtra.CAPABILITY, null).currentClass = message.classID; player.getCapability(CapPlayerExtra.CAPABILITY, null).playerInfo[CapPlayerExtraData.gold] = message.gold; return null; } } public int classID, gold; public ClassResponsePacket() { } public ClassResponsePacket(int className, int gold) { this.classID = className; this.gold = gold; } @Override public void fromBytes(ByteBuf buf) { this.classID = buf.readInt(); this.gold = buf.readInt(); } @Override public void toBytes(ByteBuf buf) { buf.writeInt(this.classID); buf.writeInt(this.gold); } } I'm pulling most of my code from the old 1.8.2 era and trying to touch it up. And this is more or less the same format Oh the packet registery (for the sides, hopefully I have them correct, I do get some action if I use a Console.Out in the request so it's at least going somewhere) INSTANCE.registerMessage(CapAttributePacketHandler.class, CapAttributePacket.class, packetId++, Side.CLIENT); INSTANCE.registerMessage(CapPlayerExtraPacketHandler.class, CapPlayerExtraPacket.class, packetId++, Side.CLIENT); INSTANCE.registerMessage(CapPlayerUpdateRequestPacketHandler.class, CapPlayerUpdateRequestPacket.class, packetId++, Side.SERVER); INSTANCE.registerMessage(ClassGUIPacketHandler.class, ClassGUIPacket.class, packetId++, Side.SERVER); INSTANCE.registerMessage(ClassRequestPacketHandler.class, ClassRequestPacket.class, packetId++, Side.SERVER); INSTANCE.registerMessage(ClassResponsePacketHandler.class, ClassResponsePacket.class, packetId++, Side.CLIENT); INSTANCE.registerMessage(ProfessionRequestPacketHandler.class, ProfessionRequestPacket.class, packetId++, Side.SERVER); INSTANCE.registerMessage(ProfessionResponsePacketHandler.class, ProfessionResponsePacket.class, packetId++, Side.CLIENT);
  18. Nevermind, apparently inquiring about a better design is not covered here. Thanks please ignore [spoiler=Original Post]I know here we don't do "Java" that's something to learn on your own, however I'm not asking for "How do I use Syntax" but a more of "How can I design this to work dynamically" I'm asking because for syncing data to and from sever/client requires packets, not only that but writing/reading to the NBT. I had created an Attributes Capability which was easy if I just had an Int[] with some static named indexes and tags (which honestly I should make into an Enum that has index + tag) Now I'm creating seperate MobExtra and PlayerExtra capabilities that will work with the attributes (attributes are generic enough everyone can get them) my challenge is now with the PlayerExtra fields are not stored as Arrays[] but as normal variables. This makes me do something stupid like this: [spoiler=Code] public NBTBase writeData() { NBTTagCompound tag = new NBTTagCompound(); tag.setInteger("currentClass", currentClass); tag.setInteger("currentProfession", currentProfession); tag.setInteger("skill1", skill1); tag.setInteger("skill2", skill2); tag.setInteger("gold", gold); tag.setFloat("bonusHp", bonusHp); tag.setFloat("bonusMana", bonusMana); tag.setFloat("bonusStam", bonusStam); tag.setFloat("bonusHpRegen", bonusHpRegen); tag.setFloat("bonusManaRegen", bonusManaRegen); tag.setFloat("bonusStamRegen", bonusStamRegen); tag.setFloat("currentMana", currentMana); tag.setFloat("currentStam", currentStam); return tag; } public void readData(NBTBase nbt) { NBTTagCompound tag = (NBTTagCompound)nbt; currentClass = tag.getInteger("currentClass"); currentProfession = tag.getInteger("currentProfession"); skill1 = tag.getInteger("skill1"); skill2 = tag.getInteger("skill2"); gold = tag.getInteger("gold"); bonusHp = tag.getFloat("bonusHp"); bonusMana = tag.getFloat("bonusMana"); bonusStam = tag.getFloat("bonusStam"); bonusHpRegen = tag.getFloat("bonusHpRegen"); bonusManaRegen = tag.getFloat("bonusManaRegen"); bonusStamRegen = tag.getFloat("bonusStamRegen"); currentMana = tag.getFloat("currentMana"); currentStam = tag.getFloat("currentStam"); } public Object[] compressData() { Object[] data = new Object[numberOfInts + numberOfFloats]; int indexer = 0; data[indexer++] = currentClass; data[indexer++] = currentProfession; data[indexer++] = skill1; data[indexer++] = skill2; data[indexer++] = gold; data[indexer++] = bonusHp; data[indexer++] = bonusMana; data[indexer++] = bonusStam; data[indexer++] = bonusHpRegen; data[indexer++] = bonusManaRegen; data[indexer++] = bonusStamRegen; data[indexer++] = currentMana; data[indexer++] = currentStam; return data; } public void decompressData(Object[] data) { int indexer = 0; currentClass = (int)data[indexer++]; currentProfession = (int)data[indexer++]; skill1 = (int)data[indexer++]; skill2 = (int)data[indexer++]; gold = (int)data[indexer++]; bonusHp = (float)data[indexer++]; bonusMana = (float)data[indexer++]; bonusStam = (float)data[indexer++]; bonusHpRegen = (float)data[indexer++]; bonusManaRegen = (float)data[indexer++]; bonusStamRegen = (float)data[indexer++]; currentMana = (float)data[indexer++]; currentStam = (float)data[indexer++]; } public static int dataSize() { return numberOfInts + numberOfFloats; } Object[] data = new Object[(CapPlayerExtraData.dataSize())]; public CapPlayerExtraPacket(){} public CapPlayerExtraPacket(Object[] data) { this.data = data; } @Override public void fromBytes(ByteBuf buf) { for (int index = 0; index < CapPlayerExtraData.numberOfInts; index++) { data[index] = buf.readInt(); } for (int index = CapPlayerExtraData.numberOfInts; index < CapPlayerExtraData.dataSize(); index++) { data[index] = buf.readFloat(); } } @Override public void toBytes(ByteBuf buf) { for (int index = 0; index < CapPlayerExtraData.numberOfInts; index++) { buf.writeInt((int) data[index]); } for (int index = CapPlayerExtraData.numberOfInts; index < CapPlayerExtraData.dataSize(); index++) { buf.writeFloat((float) data[index]); } } My TL;DR is If I have over 10 vars that are not in a List<> or Array[] what's and easy way to create a FiFo system that understands what datatype the injected variable is. So when Reading/Writing to NBT or message Buffer I simply just need to use loops to go through, making it so I just have to remember to add/remove from the FiFo System if I make or remove variables.
  19. You can try the "PlayerEvent.ItemCraftedEvent" and if the items "crafted" is your milk bottle give 2 more (3 total) I'm not sure if the the player.inventory.addItem also handles a full inventory (aka throws excess on the ground) or you need to handle that as well. EDIT: I'm not sure if the exact command method is "addItem" just a rough guess
  20. Build as in "gradlew build" compile into a .jar Or you mean when you "run" your mod in the test environment (build and launch)? As when I setup the 1.10.2 work space I had an error regarding the JRE, so I just went into some configurations and removed the issue by telling it what one to use (I have 1.6 and 1.8 JREs and JDKs).
  21. I might be wrong as I'm getting back into modding again, however someone will correct me if I am. If you're looking at blocks the map color would be what will be used to put a "pixel" on a map (craft a map in MC and watch it render the area)
  22. do you have JRE1.6 and a JDK1.6 installed on your PC? You may have to go to (in eclipse) Project > Properties > Java Build Path and import/add the correct libraries for eclipse so it knows what to use to create a java VM instance
  23. Wow I feel dumb now, Yes Choonster was right, I just never saw it. In my ambition to make this capability easy to add or remove new stats, I directly referenced the "int[] attributes" var in CapAttributesData.class from the Packet, which of course asked me to make it static, which silly me just went "Ok sure" completely forgetting what static does or at least everything it does. I can't believe I overlooked it for 3 days. I'd also like to thank Animefan8888 and you too jabelar for having a look. @jabelar: I didn't mind the custom packets too much, however I know for quite a few of my systems (mainly GUIs) I had to have a request and response packet for a few IEEP (and now going to be Capability) so the client can send, and get told by the server if their request was valid (Enough mana, gold, etc) [spoiler=long winded chat]Anyways your actual question was "Also, where in your packet to you indicate which entity should get the synced information?" Currently it's in the "CapAttributePacket.CapAttributePacketHandler.onMessage()" method, where it reaches into the proxy to get a player object (from the proxies) and then send the data off to that, and just assigns the read data to it. I just followed someone elses code to get it working. But I know I will be redoing the packets to function the way I had my IEEPs working which was when a player connects they check a bool in their IEEP to see if they had been init'd yet, it defaults to false so clients will always ask on their first update, in which the server sends them the raw values it has saved. Then after that packets are sent only when needed (Mana change, stamina change, stat change, etc) Most of the Mob stats can stay on the server side as there won't be anything the player can do to view them, as I will be making a few new capabilities more geared towards unique Player and Mob values (Player Gold, Mob Boss Name, Player Class, etc) I managed to rip some MC code for getting an entity from the LoS so for some overlay rendering will be asking a viewed mob some basic info
  24. Sadly I'm still having the issue of the capabilities being returned all as the same regardless of it being the player or a mob or newly generated mob. This is creating a damper on things as I haven't gotten to the "more than one player" tests and if it's going this route it may as well be the last player to have their stats changed to update every player, and as well as that but mobs too.
  25. Few of them appear to be some ModInfo being unable to connnect and get info. Don't think they are critical, The YggdrasilAuthenticationService is just that w/e profile you are using didn't manage to reach an auth server and verify that your profile is an offical one (if you're loading this up through your IDE you most likely got assigned a player### at random there is a way to setup the run config to use your profile if you don't like seeing that error. So you're getting quite a few timeouts (firewall blocking? no internet?) not fatal and it seems you have "--username=" in the run config you might have forgot the "--password=" which is why you get that final auth error. Not fatal.
×
×
  • Create New...

Important Information

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