Jump to content
Search In
  • More options...
Find results that contain...
Find results in...


  • Posts

  • Joined

  • Last visited

Everything posted by Eastonium

  1. Another very related question: How do I get it to send the data when a player needs to get its first update? Right now it appears empty when I initially open the world until I change the contents of the tank.
  2. Thank you! I think this is just what I needed!
  3. I'm trying to create a generic tank that can hold any fluid, and has that fluid rendered on the block, as well as in the GUI. My current step in getting all of that to work is finding out how to properly send fluid updates to the client. I know packets have to be used for this is some way, but I've seen multiple ways of doing it. Here are the ways I've seen: Using the getDataPacket() and onDataPacket() functions (in your tile entity), but I haven't seen how/where those are supposed to be triggered. Using a custom packet using your mod's own packet handler. (I don't yet know how to use packets like this, and haven't seen a clean example of it.) So, how is the best way to do this?
  4. I've tried everything you suggested, but still no luck. Nothing has changed. My updated code will be on my initial post. EDIT: I have also found that if you make another mob ride this entity, kill the entity (not the mob) and relog, the mob disappears. This happens in creative mode as well. Is it possible it is trying to kill everything that is riding my entity? EDIT AGAIN: I found the source of the problem. It wasn't my entity (although it did have some other issues as jabelar pointed out). The issue is that I was cancelling the event when you tried to dismount this entity. However, I was not checking if me entity was dead when you tried to dismount. This, when trying to kill my entity, it would try to dismount everything, get stopped, and mess up everything.
  5. I'm currently trying to make an entity that you can hit while riding. However, when you give this entity enough damage to kill it, it is dying server-side but not client side. Another peculiarity is that this issue does not occur if you're in creative mode, and if you switch to creative mode while riding the entity when should be dead, it will die and you'll dismount. I've done some debugging and have found that the damage update from the final blow to the entity is not getting sent to the client, but any damage updates before that are. This is confirmed to happen with both attacking player damage and damage from lava. I'll keep looking into this issue, but if someone knows what might be causing this, or how other rideable entities accomplish this, please let me know! EDIT: Current Entity Code public class EntityFreezeIce extends Entity { private static final DataParameter<Float> HEALTH = EntityDataManager.<Float>createKey(EntityFreezeIce.class, DataSerializers.FLOAT); public EntityFreezeIce(World worldIn) { super(worldIn); this.preventEntitySpawning = true; this.setSize(0.7F, 1.5F); } public EntityFreezeIce(World worldIn, Entity entityIn) { this(worldIn); this.setPosition(entityIn.posX, entityIn.posY, entityIn.posZ); this.setRotation(entityIn.rotationYaw, 0.0F); this.motionX = entityIn.motionX; this.motionY = entityIn.motionY; this.motionZ = entityIn.motionZ; this.setDamage(7.0F); entityIn.startRiding(this, true); } @Override protected void entityInit() { this.dataManager.register(HEALTH, Float.valueOf(0.0F)); } public void setDamage(float damage) { this.dataManager.set(HEALTH, Float.valueOf(damage)); } public float getDamage() { return ((Float)this.dataManager.get(HEALTH)).floatValue(); } @Nullable @Override public AxisAlignedBB getCollisionBox(Entity entityIn) { return entityIn.canBePushed() ? entityIn.getEntityBoundingBox() : null; } @Nullable @Override public AxisAlignedBB getCollisionBoundingBox() { return this.getEntityBoundingBox(); } @Override public boolean canBePushed() { return false; } @Override public boolean canBeCollidedWith() { return !this.isDead; } @Override public boolean canRiderInteract() { return !this.isDead; } @Override public double getMountedYOffset() { return 0.0D; } @Override public boolean attackEntityFrom(DamageSource source, float amount) { NuiCraft.logger.log(Level.INFO, world.isRemote + " " + this.isDead + " " + this.getDamage()); if (!this.world.isRemote && !this.isDead) { if (this.isEntityInvulnerable(source)) { return false; } else { this.setBeenAttacked(); this.setDamage(this.getDamage() - amount); boolean fromCreativePlayer = source.getTrueSource() instanceof EntityPlayer && ((EntityPlayer)source.getTrueSource()).capabilities.isCreativeMode; if (/*fromCreativePlayer || */this.getDamage() <= 0.0F) { this.setDead(); } NuiCraft.logger.log(Level.INFO, world.isRemote + " " + this.isDead + " " + this.getDamage()); return true; } } else { return true; } } @Override protected void readEntityFromNBT(NBTTagCompound compound) { this.setDamage(compound.getFloat("health")); } @Override protected void writeEntityToNBT(NBTTagCompound compound) { compound.setFloat("health", this.getDamage()); } } SOLUTION: I was cancelling the dismount event for this entity, but did not include a check to see if this entity was dead. Solved by only cancelling the dismount event if my entity was still alive.
  6. First, I believe "recipes" is correct, as that is what I am using currently. Either that or both "recipe" and "recipes" works? I just tested what you have here, and can confirm that my test recipe (basically identical) also did not load, and did not error either. You're not crazy! I have a similar recipe that uses a shaped ore recipe that works though, so try changing the recipe type to "forge:ore_shaped". If it works, I'm guessing you might have another problem: the recipe book will try to place the items in like "xxx", "x--", "---". If it does, there are a couple problems with forge that need to be fixed.
  7. Finally, someone replied! When are you getting the infinite loop? (hopper-pull, shift-click...) Also, I made my modifications to the mergeItemStack() function when I came across problems while shift-clicking, and I tested it and it worked fine for me. How is shift-clicking not working for you? I'm determined to get this added to forge (hopefully) now that I know others wish this were a thing.
  8. Is there a way to override the texture for a filled universal bucket of a new fluid? Currently you're not given many options when you call FluidRegistry.addBucketForFluid() If this isn't doable right now, I think it might make a good feature.
  9. I was more or less hoping he had the same problem I have and that if not I could compare my code to his if he got his working. Which more or less (I say that a lot) worked, my problem was also in my blockstates file, on the same line even. I had misspelled the name of my liquid after "fluid": Thanks for your reply
  10. I have the exact same problem, hopefully someone will help us soon.
  11. I recently added a slot to a container I had, and overrided the getSlotStackLimit() function. However, when I shift-clicked items from my inventory, the value I set in getSlotStackLimit() was completely ignored. I ended up having to override the mergeItemStack() function in my container class to account for the slot stack limit. I think this would be a good thing to change for all instances however, and given forge already changes the mergeItemStack() function to make sure that the item (to put in) is valid for the slot, I don't see why this shouldn't be added. Here's the new version of the function that I came up with: //Changed to be sensitive to Slot stack limits @Override protected boolean mergeItemStack(ItemStack stack, int startIndex, int endIndex, boolean reverseDirection){ boolean flag = false; int i = startIndex; if (reverseDirection) i = endIndex - 1; if (stack.isStackable()){ while (stack.stackSize > 0 && (!reverseDirection && i < endIndex || reverseDirection && i >= startIndex)){ Slot slot = (Slot)this.inventorySlots.get(i); ItemStack itemstack = slot.getStack(); int maxLimit = Math.min(stack.getMaxStackSize(), slot.getSlotStackLimit()); if (itemstack != null && areItemStacksEqual(stack, itemstack)){ int j = itemstack.stackSize + stack.stackSize; if (j <= maxLimit){ stack.stackSize = 0; itemstack.stackSize = j; slot.onSlotChanged(); flag = true; }else if (itemstack.stackSize < maxLimit){ stack.stackSize -= maxLimit - itemstack.stackSize; itemstack.stackSize = maxLimit; slot.onSlotChanged(); flag = true; } } if (reverseDirection){ --i; }else ++i; } } if (stack.stackSize > 0){ if (reverseDirection){ i = endIndex - 1; }else i = startIndex; while (!reverseDirection && i < endIndex || reverseDirection && i >= startIndex){ Slot slot1 = (Slot)this.inventorySlots.get(i); ItemStack itemstack1 = slot1.getStack(); if (itemstack1 == null && slot1.isItemValid(stack)){ // Forge: Make sure to respect isItemValid in the slot. if(stack.stackSize <= slot1.getSlotStackLimit()){ slot1.putStack(stack.copy()); slot1.onSlotChanged(); stack.stackSize = 0; flag = true; break; }else{ itemstack1 = stack.copy(); stack.stackSize -= slot1.getSlotStackLimit(); itemstack1.stackSize = slot1.getSlotStackLimit(); slot1.putStack(itemstack1); slot1.onSlotChanged(); flag = true; } } if (reverseDirection){ --i; }else ++i; } } return flag; } I'm not currently using 4 spaces or the other formatting stuff, but I can change that if need be.
  12. I've been updating my mod from 1.8.8 to 1.10.2 the last couple days (boy, is it easy compared to most updates), but I've come across multiple instances where I'm either using or overriding deprecated functions. For example: using GameRegistry.registerBlock(...) using GameRegistry.registerItem(...) overriding Item.getItem(...) overriding Block.isFullCube(...) **https://github.com/Eastonium/Nuicraft** I know that I should update the GameRegsitry.registerBlock/Item(...) ones, but should I worry about the ones i'm overriding? Also, despite the deprecated functions, my mod works 100% as far as I have tested. Thank you in advance for your help
  13. ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(Bionicle.Bamboo), 0, new ModelResourceLocation("bionicle:Bamboo", "inventory")); Well, thanks! I thought I had tried this before, but I guess not the right way.
  14. So, I have a block with the textures registered like this: ModelLoader.setCustomStateMapper(Bionicle.BambooBlock, (new StateMap.Builder()).ignore(new IProperty[] {BlockBamboo.AGE}).build()); How do I change/define the item model for that block?
  15. I'm not asking to be able to enchant items in the enchantment table. I'm asking how I could have what the MC Wiki calls "secondary items". I have an item that I would like to be able to use Efficency and Fortune, but nothing else. Is there some way to do this?
  16. I ended up solving it, you can see my solution on my original post. I had to tell it to use my blank texture for the overlay in getArmorTexture()
  17. I'm working on making some armor similar to leather in that it can be colored with dyes. So far, I have the Item side of things working, and the sprite gets colored properly. How would I go about getting the armor to be colored as well? I don't know where to start even after looking at the vanilla code. Also, would this change if I'm using a custom model for the armor? Item Class: public class ItemMask extends ItemArmor { public static final int DEFAULT_COLOR = 11324652; public ItemMask(){ super(ArmorMaterial.LEATHER, 0, 0); //this.hasSubtypes = true; this.setMaxDamage(0); this.setCreativeTab(Bionicle.bioMaskTab); } @Override public String getArmorTexture(ItemStack stack, Entity entity, int slot, String layer){ return Bionicle.MODID + ":textures/models/masks/" + this.getUnlocalizedName().substring(13) + "_5.png"; } /*@SideOnly(Side.CLIENT) @Override public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armorSlot, ModelBiped _default){ ModelBiped armorModel = null; if(itemStack != null){ if(itemStack.getItem() instanceof ItemMataMask){ if(this == Bionicle.maskMataAkaku){ armorModel = Bionicle.proxy.getArmorModel(0);//Akaku Model }else armorModel = Bionicle.proxy.getArmorModel(-1);//Generic Model } } if(armorModel != null){ armorModel.bipedHead.showModel = false; armorModel.bipedHeadwear.showModel = armorSlot == 0; armorModel.bipedBody.showModel = false; armorModel.bipedRightArm.showModel = false; armorModel.bipedLeftArm.showModel = false; armorModel.bipedRightLeg.showModel = false; armorModel.bipedLeftLeg.showModel = false; armorModel.isSneak = entityLiving.isSneaking(); armorModel.isRiding = entityLiving.isRiding(); armorModel.isChild = entityLiving.isChild(); armorModel.heldItemRight = entityLiving.getEquipmentInSlot(0) != null ? 1 :0; if(entityLiving instanceof EntityPlayer){ armorModel.aimedBow =((EntityPlayer)entityLiving).getItemInUseDuration() > 2; } return armorModel; } return null; }*/ @Override public boolean hasColor(ItemStack stack){ return !stack.hasTagCompound() ? false : (!stack.getTagCompound().hasKey("display", 10) ? false : stack.getTagCompound().getCompoundTag("display").hasKey("color", 3)); } @Override public int getColor(ItemStack stack){ NBTTagCompound nbttagcompound = stack.getTagCompound(); if (nbttagcompound != null){ NBTTagCompound nbttagcompound1 = nbttagcompound.getCompoundTag("display"); if (nbttagcompound1 != null && nbttagcompound1.hasKey("color", 3)){ return nbttagcompound1.getInteger("color"); } } return DEFAULT_COLOR; } public void removeColor(ItemStack stack){ NBTTagCompound nbttagcompound = stack.getTagCompound(); if (nbttagcompound != null){ NBTTagCompound nbttagcompound1 = nbttagcompound.getCompoundTag("display"); if (nbttagcompound1.hasKey("color")){ nbttagcompound1.removeTag("color"); } } } public void setColor(ItemStack stack, int color){ NBTTagCompound nbttagcompound = stack.getTagCompound(); if (nbttagcompound == null){ nbttagcompound = new NBTTagCompound(); stack.setTagCompound(nbttagcompound); } NBTTagCompound nbttagcompound1 = nbttagcompound.getCompoundTag("display"); if (!nbttagcompound.hasKey("display", 10)){ nbttagcompound.setTag("display", nbttagcompound1); } nbttagcompound1.setInteger("color", color); } } Any *useful* help would be appreciated! EDIT: Finally Figured it out! After finding some very useful information from Draco18s on other threads, I found my problem. (Thanks indirectly) I initially tried creating a texture that was completely transparent with "_overlay" in the name like leather armor has, but that didn't work. HERES THE KEY TO GET THIS TO WORK EVERYBODY: In your getArmorTexture() function if you always return the texture you're wanting to have colored, then it will also use that for the overlay texture, which doesn't get colored. The way to avoid that is to add a null check on the String argument for the function. When rendering normally it passes in null, but for overlay it passes the string "overlay". So don't do this: @Override public String getArmorTexture(ItemStack stack, Entity entity, int slot, String layer){ return "MODID:some/path/to/your/colorized/texture.png"; } DO THIS: @Override public String getArmorTexture(ItemStack stack, Entity entity, int slot, String layer){ if(layer == null){ return "MODID:some/path/to/your/colorized/texture.png"; }else return "MODID:some/path/to/a/blank/texture.png"; } I hope people find this and use it!!
  18. But both of the changes I make to the tank both happen within the !isRemote section. Am I just missing something really obvious?
  19. Did you read all of my post? It does show changes on clientside, but only in one circumstance.
  20. I have a tank implemented on my tile entity, but the client isn't getting updated when I remove fluid from the tank bit by bit, but it does work when I fill the tank completely from being empty. Here's my update function from my TileEntity/TileInventory class. @Override public void update(){ boolean hasLava = this.hasLava(); int lavaAmount = this.tank.getFluidAmount(); boolean needsUpdate = false; //When I print out "lavaAmount" here, I get either 0/1000 (empty/full) when run by the client, but the actual amount when run by the server /*if(this.burnTimeRemaining > 0){ --this.burnTimeRemaining; }*/ if(!this.worldObj.isRemote){ if(!hasLava && this.forgeItemstacks[FIRST_FUEL_SLOT] != null && this.forgeItemstacks[FIRST_FUEL_SLOT].getItem() == Items.lava_bucket){//TODO Change to include all items that hold fluids this.fill(null, new FluidStack(FluidRegistry.LAVA, FluidContainerRegistry.BUCKET_VOLUME), true); this.forgeItemstacks[FIRST_FUEL_SLOT] = this.forgeItemstacks[FIRST_FUEL_SLOT].getItem().getContainerItem(forgeItemstacks[FIRST_FUEL_SLOT]); } if(/*this.secondsOfFuelRemaining() > 0*/ hasLava && this.canSmelt()){ this.tank.drain(5, true); ++this.cookTime; if(this.cookTime == COOK_TIME_FOR_COMPLETION){ this.cookTime = 0; this.smeltItem(); needsUpdate = true; } } if (lavaAmount != this.tank.getFluidAmount()){ needsUpdate = true; //TODO BlockMaskForge.updateFurnaceBlockState(this.isBurning(), this.worldObj, this.pos.getX(), this.pos.getY(), this.pos.getX()); } } if (needsUpdate){ this.markDirty(); } } Is there something I'm missing here? I'm sure you'll probably need more information to help me solve this, just let me know what you need. EDIT: Solved it myself. Turns out when I was updating the IInventory setFeild() function, I was always adding fluid rather than adding/removing depending on what it should be. So I changed this: @Override public void setField(int id, int value){ if(id == COOK_FIELD_ID){ cookTime = (short)value; }else if(id == FUEL_AMOUNT_FIELD_ID){ this.fill(null, new FluidStack(FluidRegistry.LAVA, value), true); }else{ System.err.println("Invalid field ID in TileInventorySmelting.setField:" + id); } } To this: @Override public void setField(int id, int value){ if(id == COOK_FIELD_ID){ cookTime = (short)value; }else if(id == FUEL_AMOUNT_FIELD_ID){ FluidStack flStack = new FluidStack(FluidRegistry.LAVA, Math.abs(this.tank.getFluidAmount() - value)); if(value > this.tank.getFluidAmount()){ this.fill(null, flStack, true); }else if(value < this.tank.getFluidAmount()){ this.drain(null, flStack, true); } }else{ System.err.println("Invalid field ID in TileInventorySmelting.setField:" + id); } }
  21. Thanks! I got it sorted out! It just seems really complicated for something that was so simple in 1.7 and will be simple in 1.9. I guess I'll just have to wait until I can make it simple again.
  22. Alright, got that set up. I'm having another issue with it though. I'm getting the pink/black checkered block for the specific damaged item, but not for any other damages. Here's what I have: public ModelResourceLocation getModelLocation(ItemStack stack) { if(stack.getItem() == Bionicle.heatstoneLighter){ if(stack.getItemDamage() == 128){ return new ModelResourceLocation(Bionicle.heatstoneLighter.getRegistryName() + "_spent", "inventory"); }else return new ModelResourceLocation(Bionicle.heatstoneLighter.getRegistryName(), "inventory"); }else return null; } I have the _spent version of the model in the same folder right next to the regular one (and spelled correctly), but like I said, its not showing up. And I've confirmed that it is getting to that point where it returns the _spent version of the ModelResourceLocation. Its not throwing any errors in the console either.
  23. Do I need to create a new class and implement ItemMeshDefinition, or do I implement it in the item class of which I want the different textures? Also, should the call of ModelLoader.setCustomMeshDefinition go in my Client or Common proxy? Since it deals with textures I've put it in Client, but I don't want to take any chances here.
  • Create New...

Important Information

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