Jump to content

TLHPoE

Members
  • Posts

    638
  • Joined

  • Last visited

Posts posted by TLHPoE

  1. 18 minutes ago, Draco18s said:

    Yes, I'm aware now. In the other post you referenced RecipeSorter, which I assumed was the main method of registering the recipe. Didn't see the mold_bucket recipe though, so my bad.

  2. 14 minutes ago, diesieben07 said:

    You don't need RecipeSorter anymore. If your factory is registered (like it is), you can just create JSON files like for any other recipe using that factory.

    So the recipe I'm adding is to craft any amount of potions with my item, and the result is my item with some more NBT data attached to it. What would the JSON file look like? I've tried just adding a generic shapeless recipe with my item as both the ingredient and result:

    Spoiler
    
    {
      "type": "minecraft:crafting_shapeless",
      "group": "quickconsume",
      "ingredients": [
        {
          "item": "quickconsume:potion_bag"
        }
      ],
      "result": {
        "item": "quickconsume:potion_bag"
      }
    }

     

     

    The recipe doesn't load. Is there a specific type I'm missing? I can't seem to find any recipes like this in Minecraft to reference.

  3. Hello, I was referencing this post in order to add my dynamic recipe, but it recommends using a class (RecipeSorter) that is marked as deprecated. How do I register my recipe?

     

    I have my IRecipe class (plus its factory):

    Spoiler
    
    package com.kain24.quickconsume.recipe;
    
    import com.google.gson.JsonObject;
    import com.kain24.quickconsume.item.ItemPotionBag;
    import net.minecraft.inventory.InventoryCrafting;
    import net.minecraft.item.ItemPotion;
    import net.minecraft.item.ItemStack;
    import net.minecraft.item.crafting.IRecipe;
    import net.minecraft.potion.PotionUtils;
    import net.minecraft.world.World;
    import net.minecraftforge.common.crafting.IRecipeFactory;
    import net.minecraftforge.common.crafting.JsonContext;
    import net.minecraftforge.registries.IForgeRegistryEntry;
    
    public class PotionBagRecipe
            extends IForgeRegistryEntry.Impl<IRecipe>
            implements IRecipe {
        @Override
        public boolean matches(InventoryCrafting inv, World worldIn) {
            ItemStack bag = null;
            ItemStack potion = null;
            int amt = 0;
    
            for(int i = 0; i < inv.getSizeInventory(); i++) {
                ItemStack is = inv.getStackInSlot(i);
    
                if(is.getItem() instanceof ItemPotionBag) {
                    if(bag != null) {
                        return false; //2 bags in grid = NO
                    } else {
                        bag = is;
                    }
                } else if(is.getItem() instanceof ItemPotion) {
                    if(potion != null) {
                        if(PotionUtils.getFullEffectsFromItem(is).equals(PotionUtils.getFullEffectsFromItem(potion))) {
                            amt++;
                        } else {
                            return false; //2 different potions = NO
                        }
                    } else {
                        potion = is;
                        amt++;
                    }
                }
            }
    
            if(bag != null && potion != null) {
                ItemStack storedPotion = ItemPotionBag.getPotionType(bag);
    
                if(storedPotion.isEmpty() ||
                        PotionUtils.getFullEffectsFromItem(storedPotion).equals(PotionUtils.getFullEffectsFromItem(potion))) {
                    if(ItemPotionBag.getAmountStored(bag) + amt > ItemPotionBag.getMax()) {
                        return false; //Overfill bag = NO
                    }
    
                    return true;
                }
            }
    
            return false;
        }
    
        @Override
        public ItemStack getCraftingResult(InventoryCrafting inv) {
            ItemStack bag = null;
            ItemStack potion = null;
            int amt = 0;
    
            for(int i = 0; i < inv.getSizeInventory(); i++) {
                ItemStack is = inv.getStackInSlot(i);
    
                if(is.getItem() instanceof ItemPotionBag) {
                    bag = is.copy();
                } else if(is.getItem() instanceof ItemPotion) {
                    potion = is;
                    amt++;
                }
            }
    
            ItemPotionBag.setPotionType(bag, potion);
            ItemPotionBag.setAmountStored(bag, ItemPotionBag.getAmountStored(bag) + amt);
    
            return bag;
        }
    
        @Override
        public boolean canFit(int width, int height) {
            return width * height > 1;
        }
    
        @Override
        public ItemStack getRecipeOutput() {
            return ItemStack.EMPTY;
        }
    
        @Override
        public boolean isDynamic() {
            return true;
        }
    
        public static class Factory implements IRecipeFactory {
            @Override
            public IRecipe parse(JsonContext ctx, JsonObject json) {
                return new PotionBagRecipe();
            }
        }
    }

     

     

     

    And then I have my _factories.json (located in assets/quickconsume/recipes):

    Spoiler
    
    {
      "recipes": {
        "potion_bag_store": "com.kain24.quickconsume.recipe.PotionBagRecipe$Factory"
      }
    }

     

     

     

  4. Hello,

    I am putting together a mod pack for me and my friends, but when pregenerating chunks using the Chunk Pregenerator mod it closes the server without a crash log at what seems like random times.

     

    Here is a snippet of the end of a log:

    Spoiler

    [21:36:00] [Server thread/WARN] [FML]: Roguelike Dungeons loaded a new chunk [17, 48] in dimension 0 (overworld) while populating chunk [16, 56], causing cascading worldgen lag.
    [21:36:00] [Server thread/WARN] [FML]: Please report this to the mod's issue tracker. This log can be disabled in the Forge config.
    [21:36:00] [Server thread/WARN] [FML]: Roguelike Dungeons loaded a new chunk [18, 47] in dimension 0 (overworld) while populating chunk [16, 56], causing cascading worldgen lag.
    [21:36:00] [Server thread/WARN] [FML]: Please report this to the mod's issue tracker. This log can be disabled in the Forge config.
    [21:36:00] [Server thread/WARN] [FML]: Roguelike Dungeons loaded a new chunk [17, 47] in dimension 0 (overworld) while populating chunk [16, 56], causing cascading worldgen lag.
    [21:36:00] [Server thread/WARN] [FML]: Please report this to the mod's issue tracker. This log can be disabled in the Forge config.
    [21:36:00] [Server thread/WARN] [FML]: Roguelike Dungeons loaded a new chunk [19, 57] in dimension 0 (overworld) while populating chunk [16, 56], causing cascading worldgen lag.
    [21:36:00] [Server thread/WARN] [FML]: Please report this to the mod's issue tracker. This log can be disabled in the Forge config.
    [21:36:03] [Server thread/INFO] [FML]: Auto Restart enabled. Cleaned up all data now killing the game
    [21:36:03] [Server thread/WARN] [FML]: Java has been asked to exit (code 0)
    [21:36:03] [Server thread/WARN] [FML]: This is an abortive exit and could cause world corruption or other things
    [21:36:03] [Server thread/WARN] [FML]: Exit trace:
    [21:36:03] [Server thread/WARN] [FML]:     pregenerator.impl.processor.ChunkProcessor.onServerTickEvent(ChunkProcessor.java:149)
    [21:36:03] [Server thread/WARN] [FML]:     net.minecraftforge.fml.common.eventhandler.ASMEventHandler_163_ChunkProcessor_onServerTickEvent_ServerTickEvent.invoke(.dynamic)
    [21:36:03] [Server thread/WARN] [FML]:     net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90)
    [21:36:03] [Server thread/WARN] [FML]:     net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:182)
    [21:36:03] [Server thread/WARN] [FML]:     net.minecraftforge.fml.common.FMLCommonHandler.onPostServerTick(FMLCommonHandler.java:265)
    [21:36:03] [Server thread/WARN] [FML]:     net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:712)
    [21:36:03] [Server thread/WARN] [FML]:     net.minecraft.server.MinecraftServer.run(MinecraftServer.java:526)
    [21:36:03] [Server thread/WARN] [FML]:     java.lang.Thread.run(Thread.java:745)

     

     

    It occurs immediately when I create the world and run the command for pregenerator, and then again after I restart and let the task resumes for a couple of chunks (it generates a good handful before "auto restarting").

     

    I am unsure if this is Forge, Chunk Pregenerator, or the mods that generate structures. The messages along the lines of "X loaded a new chunk..." is in the log quite often, with X mainly being Roguelike Dungeons of Recurrent Complex.

     

    I removed TickDynamic, JourneyMap, and AromaBackup, but the problem persisted. Before every "auto restart," AromaBackup would state that it was creating a backup.

     

    Here is my current mod list:

    Spoiler

    Animalium 0.3.7

    AppleCore 3.1.3

    Aroma1997Core 2.0.0.0

    AttributeFix 1.0.1

    Baubles 1.5.2

    BetterBuildersWands 0.12.0.251

    BetterFps 1.4.8

    BetterQuesting 3.5.262

    BiomesOPlenty 7.0.1.2399

    Bloodmoon 1.5.3

    Chameleon 4.1.3

    Chunk Pregenerator 1.8.1

    CodeChickenLib 3.2.1.350

    CraftingRunes 1.1

    CraftTweaker2 4.1.9

    CreativeCore 1.9.25

    DeathCounter 1.0.0

    DoomlikeDungeons 1.11.1

    ExtraUtils2 1.8.2

    FamiliarFauna 1.0.10

    Farseek 2.3.1

    FriendlyFire 1.5.8

    GlobalXP 1.4

    Grue 1.3.5

    Hats 7.0.2

    Hwyla 1.8.26-B41

    iChunUtil 7.1.4

    ImprovedBackpacks 1.3.0.0

    InventoryTweaks 1.63

    Iron Chest 7.0.46.831

    IvToolkit 1.3.3

    JEI 4.11.0.206

    JustEnoughResources 0.8.8.47

    LibEx 1.0.4

    LoginShield 1.12.2-3-g7c6e7ac

    MagmaMonsters 0.3.0

    Mob Drops 0.0.1

    Mob Mash 2.4

    MobGrindingUtils 3.3.2

    NaturesCompass 1.5.1

    NetherEx 2.0.4

    NetherPortalFix 5.3.13

    OreExcavation 1.4.119

    Pam's HarvestCraft 1.12.2u

    PlayerRevive 1.2.14

    RecurrentComplex 1.4.7

    Roguelike Dungeons 1.8.0

    Solcarrot 1.3.3

    Spectrite 1.6.6

    StandardExpansion 3.4.143

    StorageDrawers 5.3.7

    The Beneath 1.4.2

    The Betweenlands 3.3.11

    Twilight Forest 3.7.424

    Wawla 2.5.257

    Waystones 4.0.54

    Wolf Armor 2.2.3.1798

     

    For my server, I have disabled Biomes 'o Plenty to test.

     

    Here is the full log, which was taken after loading an already created world and letting the pregen task resume (it resumes automatically)

     

    Edit: the debug log is too big, even for pastebin. It says virtually the same thing at the end.

  5. 4 hours ago, Choonster said:

     

    What makes you think the cooldown isn't being set to 100? Are you looking at data from the client or from the server?

     

    Capabilities aren't automatically synced between the server and client, you need to sync them yourself. I explain how to sync item capabilities here.

     

    Both times I access the capabilities are server side.

  6. Goal: Create a cool down system for firing a weapon, so getting and setting an integer within an itemstack

    How: Using forge capability system

    Problem: Can't set (but can retrieve capability)

     

    IRepeaterData:

    package com.kain.slippworld.data.repeater;
    
    public interface IRepeaterData {
    	public int getCoolDown();
    
    	public void setCoolDown(int coolDown);
    }

     

    RepeaterData:

    package com.kain.slippworld.data.repeater;
    
    public class RepeaterData implements IRepeaterData {
    	private int coolDown;
    	
    	@Override
    	public int getCoolDown() {
    		return coolDown;
    	}
    
    	@Override
    	public void setCoolDown(int coolDown) {
    		this.coolDown = coolDown;
    	}
    
    }

     

    RepeaterCapability:

    package com.kain.slippworld.data.repeater;
    
    import com.kain.slippworld.*;
    import com.kain.slippworld.data.*;
    
    import net.minecraft.item.*;
    import net.minecraft.nbt.*;
    import net.minecraft.util.*;
    import net.minecraftforge.common.capabilities.*;
    
    public class RepeaterCapability {
    	public static final ResourceLocation NAME = new ResourceLocation(Reference.MOD_ID, "_Repeater");
    
    	@CapabilityInject(IRepeaterData.class)
    	public static final Capability<IRepeaterData> REPEATER_DATA_CAPABILITY = null;
    
    	public static final EnumFacing DEFAULT_FACING = null;
    
    	public static void register() {
    		CapabilityManager.INSTANCE.register(IRepeaterData.class, new Capability.IStorage<IRepeaterData>() {
    			@Override
    			public NBTBase writeNBT(Capability<IRepeaterData> capability, IRepeaterData instance, EnumFacing side) {
    				return new NBTTagInt(instance.getCoolDown());
    			}
    
    			@Override
    			public void readNBT(Capability<IRepeaterData> capability, IRepeaterData instance, EnumFacing side, NBTBase nbt) {
    				instance.setCoolDown(((NBTTagInt) nbt).getInt());
    			}
    		}, () -> new RepeaterData());
    	}
    
    	public static IRepeaterData getCapability(ItemStack itemStack) {
    		return itemStack != null && itemStack.hasCapability(REPEATER_DATA_CAPABILITY, DEFAULT_FACING) ? itemStack.getCapability(REPEATER_DATA_CAPABILITY, DEFAULT_FACING) : null;
    	}
    
    	public static ICapabilityProvider createProvider() {
    		return new GenericCapabilityProvider<>(REPEATER_DATA_CAPABILITY, DEFAULT_FACING);
    	}
    
    	public static ICapabilityProvider createProvider(IRepeaterData repeaterData) {
    		return new GenericCapabilityProvider(REPEATER_DATA_CAPABILITY, DEFAULT_FACING, repeaterData);
    	}
    }

     

    GenericCapabilityProvider:

    package com.kain.slippworld.data;
    
    import net.minecraft.nbt.*;
    import net.minecraft.util.*;
    import net.minecraftforge.common.capabilities.*;
    
    public class GenericCapabilityProvider<HANDLER> implements ICapabilitySerializable<NBTBase> {
    	private final Capability<HANDLER> capability;
    
    	private final EnumFacing facing;
    
    	private final HANDLER instance;
    
    	public GenericCapabilityProvider(Capability<HANDLER> capability, EnumFacing facing) {
    		this(capability, facing, capability.getDefaultInstance());
    	}
    
    	public GenericCapabilityProvider(Capability<HANDLER> capability, EnumFacing facing, HANDLER instance) {
    		this.capability = capability;
    		this.facing = facing;
    		this.instance = instance;
    	}
    
    	@Override
    	public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
    		return capability == getCapability();
    	}
    
    	@Override
    	public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
    		if(capability == getCapability()) {
    			return (T) instance;
    		}
    		return null;
    	}
    
    	@Override
    	public NBTBase serializeNBT() {
    		return getCapability().writeNBT(getInstance(), getFacing());
    	}
    
    	@Override
    	public void deserializeNBT(NBTBase nbt) {
    		getCapability().readNBT(getInstance(), getFacing(), nbt);
    	}
    
    	public Capability<HANDLER> getCapability() {
    		return capability;
    	}
    
    	public EnumFacing getFacing() {
    		return facing;
    	}
    
    	public HANDLER getInstance() {
    		return instance;
    	}
    }

     

    ItemRepeater

    package com.kain.slippworld.item.tool;
    
    import javax.annotation.*;
    
    import com.kain.slippworld.*;
    import com.kain.slippworld.data.repeater.*;
    
    import net.minecraft.creativetab.*;
    import net.minecraft.entity.*;
    import net.minecraft.entity.player.*;
    import net.minecraft.item.*;
    import net.minecraft.nbt.*;
    import net.minecraft.util.*;
    import net.minecraft.world.*;
    import net.minecraftforge.common.capabilities.*;
    import net.minecraftforge.fml.relauncher.*;
    
    public class ItemRepeater extends Item {
    	public final ToolMaterial material;
    	protected final float damage;
    	protected final int maxCoolDown;
    
    	public ItemRepeater(ToolMaterial material, float distance, int maxCoolDown) {
    		super();
    
    		...
    	}
    
    	@Override
    	public void onUpdate(ItemStack itemStack, World world, Entity e, int slot, boolean selected) {
    		super.onUpdate(itemStack, world, e, slot, selected);
    
    		if(!world.isRemote) {
    			IRepeaterData data = RepeaterCapability.getCapability(itemStack);
    
    			if(data != null) {
    				int coolDown = data.getCoolDown();
    
    				if(coolDown > 0) {
    					System.out.println("COOL DOWN");
    					data.setCoolDown(coolDown--);
    				}
    			}
    		}
    	}
    
    	...
    
    	@Override
    	@Nullable
    	public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable NBTTagCompound nbt) {
    		return RepeaterCapability.createProvider();
    	}
    
    	public void attackEntity(ItemStack itemStack, EntityLivingBase entity, EntityPlayer player) {
    		if(!player.world.isRemote) {
    			IRepeaterData data = RepeaterCapability.getCapability(itemStack);
    
    			if(data != null && data.getCoolDown() == 0) {
    				entity.hurtResistantTime = 0;
    				entity.attackEntityFrom(DamageSource.GENERIC, getDamage());
    
    				data.setCoolDown(100);
    
    				System.out.println("BANG");
    			}
    		}
    	}
    
    	public float getDamage() {
    		return damage;
    	}
    
    	public int getMaxCoolDown() {
    		return maxCoolDown;
    	}
    }

     

    ItemRepeater#attackEntity is being called externally by a packet. Right now when I right click (trigger the attackEntity method), it detects the cool down value as being 0 and outputs "BANG," but it never sets the cool down value to 100. I'm sure that there's some markDirty method somewhere but I just can't find it.

     

    I based my code around choonster's test mod.

  7. I dug around to find the source of MInecraft#objectMouseOver, and it's actually set using Entity#rayTrace. How come when I try to use the method myself it doesn't detect entities?

    	@Override
    	public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
    		if(world.isRemote) {
    			RayTraceResult ray = player.rayTrace(5F, 1F);
    			System.out.println("Casting ray");
    
    			if(ray.entityHit != null && ray.typeOfHit == Type.ENTITY && ray.entityHit instanceof EntityLivingBase) {
    				EntityLivingBase entity = (EntityLivingBase) ray.entityHit;
    
    				SlippWorld.channel.sendToServer(new MessageTargetEntity(entity, player.getHeldItem(hand)));
    
    				System.out.println("Attack sent");
    			}
    
    			for(int i = 0; i < 3; i++) {
    				Minecraft.getMinecraft().entityRenderer.itemRenderer.updateEquippedItem();
    			}
    		}
    
    		return new ActionResult(EnumActionResult.PASS, player.getHeldItem(hand));
    	}

     

    The only variable I feel iffy passing for the ray is the partialTick, which I'm not sure what to put there, only that it should be between 0F and 1F.

  8. Seeing as how no one has responded about using the actual chunk's NBT, I fixed my original method of storing my own chunk data in my WorldSavedData:

    package com.kain.slippworld;
    
    import java.util.*;
    
    import net.minecraft.nbt.*;
    import net.minecraft.util.math.*;
    import net.minecraft.world.*;
    import net.minecraft.world.storage.*;
    
    public class WorldSavedDataMod extends WorldSavedData {
    	public static final String NAME = Reference.NAME + "_WorldData";
    
    	public boolean isDragonSlain = false;
    
    	public Map<ChunkPos, NBTTagCompound> chunkData;
    
    	public WorldSavedDataMod(String name) {
    		super(name);
    
    		chunkData = new HashMap<ChunkPos, NBTTagCompound>();
    	}
    
    	public WorldSavedDataMod() {
    		this(NAME);
    	}
    
    	@Override
    	public void readFromNBT(NBTTagCompound nbt) {
    		isDragonSlain = nbt.getBoolean(Reference.DRAGON_SLAIN_TAG);
    
    		NBTTagCompound chunks = nbt.getCompoundTag(Reference.WORLD_DATA_CHUNKS);
    
    		for(String pos : chunks.getKeySet()) {
    			chunkData.put(fromString(pos), chunks.getCompoundTag(pos));
    		}
    	}
    
    	@Override
    	public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
    		nbt.setBoolean(Reference.DRAGON_SLAIN_TAG, isDragonSlain);
    
    		NBTTagCompound chunks = new NBTTagCompound();
    
    		for(ChunkPos pos : chunkData.keySet()) {
    			chunks.setTag(pos.toString(), chunkData.get(pos));
    		}
    
    		nbt.setTag(Reference.WORLD_DATA_CHUNKS, chunks);
    
    		return nbt;
    	}
    
    	public NBTTagCompound getChunkData(ChunkPos pos) {
    		NBTTagCompound nbt = chunkData.get(pos);
    
    		if(nbt == null) {
    			nbt = new NBTTagCompound();
    			chunkData.put(pos, nbt);
    		}
    
    		return nbt;
    	}
    
    	public static WorldSavedDataMod get(World w) {
    		MapStorage s = w.getMapStorage();
    		WorldSavedDataMod d = (WorldSavedDataMod) s.getOrLoadData(WorldSavedDataMod.class, NAME);
    
    		if(d == null) {
    			d = new WorldSavedDataMod();
    			s.setData(NAME, d);
    		}
    
    		return d;
    	}
    
    	public static ChunkPos fromString(String pos) {
    		pos = pos.substring(1, pos.length() - 1);
    
    		for(int i = 0; i < pos.length(); i++) {
    			if(pos.charAt(i) == ',') {
    				return new ChunkPos(Integer.parseInt(pos.substring(0, i)), Integer.parseInt(pos.substring(i + 2, pos.length())));
    			}
    		}
    
    		return null;
    	}
    }

     

  9. I'm trying to make a ray-based weapon that damages the entity that the player is aiming at. Currently I am using Minecraft#objectMouseOver on the client and sending a packet to the server for processing, but it has a limited range. Another option I saw was EntityPlayer#rayTrace method, but it never returned an entity hit.

     

    Code:

    	@Override
    	public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
    		if(world.isRemote) {
    			RayTraceResult ray = Minecraft.getMinecraft().objectMouseOver;
    
    			if(ray.typeOfHit == Type.ENTITY && ray.entityHit != null && ray.entityHit instanceof EntityLivingBase) {
    				EntityLivingBase entity = (EntityLivingBase) ray.entityHit;
    
    				SlippWorld.channel.sendToServer(new MessageTargetEntity(entity, player.getHeldItem(hand)));
    			}
    		}
    
    		return new ActionResult(EnumActionResult.SUCCESS, player.getHeldItem(hand));
    	}

     

    Is there a better option for casting a longer ray that will hit entities and blocks?

  10. 7 hours ago, Elix_x said:

    o_0

    So... which one?

    WorldSavedData is not a correct place to store per chunk data.  You have access to chunk NBT in both chunk load a save events for a reason ;).

    Did you know, that vanilla already has a ChunkPos class?

     

    Also, hash maps won't work if you don't implement hashCode and equals (use your IDE to generate them).

    ... Oops

     

    I know that the event gives access to the chunk's NBT, but I haven't been able to get the data to save at all:

    	@SubscribeEvent
    	public void chunkSave(ChunkDataEvent.Save e) {
    		World w = e.getWorld();
    
    		if(!w.isRemote) {
    			WorldSavedDataMod data = WorldSavedDataMod.get(w);
    			NBTTagCompound nbt = e.getData();
    
    			if(data.isDragonSlain) {
    				if(!nbt.hasKey(Reference.CHUNK_REJUVENATED_TAG)) {
    					nbt.setBoolean(Reference.CHUNK_REJUVENATED_TAG, true);
    
    					System.out.println("Generating new ores");
    
    					...
    
    					e.getChunk().setModified(true);
    					data.markDirty();
    				} else {
    					System.out.println("Chunk already has ores");
    				}
    			} else {
    				System.out.println("Dragon hasn't been slain yet");
    			}
    		}
    	}

    The code above is what I first tried and it doesn't save the data. The only reason I tried to store it within my WorldSavedData was because of this thread.

  11. I'm trying to use WorldSavedData to keep track of every chunk that's been loaded and assign it an NBTTagCompound. Right now I have a map that stores a custom class I made called ChunkPos as the key and the NBT tag as the entry. The ChunkPos class is mainly for converting from Chunk to a String for storing the chunk's NBT tag when loading/saving.

     

    WorldSavedData (with ChunkPos at the bottom):

    package com.kain.slippworld;
    
    import java.util.*;
    
    import net.minecraft.nbt.*;
    import net.minecraft.world.*;
    import net.minecraft.world.chunk.*;
    import net.minecraft.world.storage.*;
    
    public class WorldSavedDataMod extends WorldSavedData {
    	public static final String NAME = Reference.NAME + "_WorldData";
    
    	public boolean isDragonSlain = false;
    
    	public Map<ChunkPos, NBTTagCompound> chunkData = null;
    
    	public WorldSavedDataMod(String name) {
    		super(name);
    
    		chunkData = new HashMap<ChunkPos, NBTTagCompound>();
    	}
    
    	public WorldSavedDataMod() {
    		this(NAME);
    	}
    
    	@Override
    	public void readFromNBT(NBTTagCompound nbt) {
    		isDragonSlain = nbt.getBoolean(Reference.DRAGON_SLAIN_TAG);
    
    		NBTTagCompound chunks = nbt.getCompoundTag(Reference.WORLD_DATA_CHUNKS);
    
    		for(String string : chunks.getKeySet()) {
    			chunkData.put(new ChunkPos(string), chunks.getCompoundTag(string));
    		}
    	}
    
    	@Override
    	public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
    		nbt.setBoolean(Reference.DRAGON_SLAIN_TAG, isDragonSlain);
    
    		NBTTagCompound chunks = new NBTTagCompound();
    
    		for(ChunkPos chunk : chunkData.keySet()) {
    			chunks.setTag(chunk.toString(), chunkData.get(chunk));
    		}
    
    		nbt.setTag(Reference.WORLD_DATA_CHUNKS, chunks);
    
    		return nbt;
    	}
    
    	public NBTTagCompound getChunkData(Chunk chunk) {
    		return chunkData.get(new ChunkPos(chunk));
    	}
    
    	public void setChunkData(Chunk chunk, NBTTagCompound nbt) {
    		chunkData.put(new ChunkPos(chunk), nbt);
    	}
    
    	public static WorldSavedDataMod get(World w) {
    		MapStorage s = w.getMapStorage();
    		WorldSavedDataMod d = (WorldSavedDataMod) s.getOrLoadData(WorldSavedDataMod.class, NAME);
    
    		if(d == null) {
    			d = new WorldSavedDataMod();
    			s.setData(NAME, d);
    		}
    
    		return d;
    	}
    
    	public class ChunkPos {
    		public long x, z;
    
    		public ChunkPos(long x, long z) {
    			this.x = x;
    			this.z = z;
    		}
    
    		public ChunkPos(Chunk chunk) {
    			this(chunk.xPosition, chunk.zPosition);
    		}
    
    		public ChunkPos(String string) {
    			for(int i = 0; i < string.length(); i++) {
    				if(string.charAt(i) == ',') {
    					try {
    						this.x = Long.parseLong(string.substring(0, i));
    						this.z = Long.parseLong(string.substring(i + 1, string.length()));
    					} catch(Exception e) {
    						e.printStackTrace();
    					}
    				}
    			}
    		}
    
    		public String toString() {
    			return x + "," + z;
    		}
    	}
    }

     

    Data Attachment and Reading:

    	@SubscribeEvent
    	public void chunkLoad(ChunkDataEvent.Save e) {
    		World w = e.getWorld();
    
    		if(!w.isRemote) {
    			WorldSavedDataMod data = WorldSavedDataMod.get(w);
    			NBTTagCompound nbt = data.getChunkData(e.getChunk());
    
    			if(nbt == null) {
    				nbt = new NBTTagCompound();
    
    				data.setChunkData(e.getChunk(), nbt);
    				data.markDirty();
    
    				System.out.println("Chunk doesn't have data, creating");
    			}
    		}
    	}

     

    The problem is that the chunks are either not saved correctly or not loaded correctly (the "Chunk doesn't have data, creating" is being constantly spammed in one area). I know for a fact that the WorldSavedData class is actually being saved to the world since the isDragonSlain field is being properly saved/loaded and that the ChunkPos class is correctly converting from Chunk to String.

  12. I have a custom WorldSavedData class but marking it dirty won't save it.

     

    Where I edit values and mark it dirty:

    	@SubscribeEvent
    	public void entityDeath(LivingDeathEvent ev) {
    		EntityLivingBase e = ev.getEntityLiving();
    
    		if(!e.world.isRemote) {
    			if(e instanceof EntityWolf) {
    				WorldSavedDataMod data = WorldSavedDataMod.get(e.world);
    				
    				data.isDragonSlain = true;
    				data.markDirty();
    				
    				...
    
    			}
    		}
    	}

     

    My WorldSavedData:

    package com.kain.slippworld;
    
    import net.minecraft.nbt.*;
    import net.minecraft.world.*;
    import net.minecraft.world.storage.*;
    
    public class WorldSavedDataMod extends WorldSavedData {
    	public static final String NAME = Reference.NAME + "_WorldData";
    
    	public boolean isDragonSlain = false;
    
    	public WorldSavedDataMod() {
    		super(NAME);
    	}
    
    	@Override
    	public void readFromNBT(NBTTagCompound nbt) {
    		isDragonSlain = nbt.getBoolean(Reference.DRAGON_SLAIN_TAG);
    	}
    
    	@Override
    	public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
    		nbt.setBoolean(Reference.DRAGON_SLAIN_TAG, isDragonSlain);
    
    		return nbt;
    	}
    
    	public static WorldSavedDataMod get(World w) {
    		MapStorage s = w.getMapStorage();
    		WorldSavedDataMod d = (WorldSavedDataMod) s.getOrLoadData(WorldSavedDataMod.class, NAME);
    
    		if(d == null) {
    			d = new WorldSavedDataMod();
    			s.setData(NAME, d);
    		}
    
    		return d;
    	}
    	
    	public void save(World w) {
    		w.getMapStorage().setData(NAME, this);
    	}
    }

     

    When I kill a wolf it sets the boolean to true and it stays true, but when I exit the world and rejoin it's false.

  13. I'm trying to add a boolean to the world save file that indicates whether or not the player has done an action, in this case when they kill the ender dragon. I found the WorldInfo class and the ...AdditionalProperty methods, but I'm not quite sure how the system for custom data works. It seems that when you call get method it returns an entry from the overall map, but when you call the set method it replaces the entire map. How would I save my data without clearing other mods' preexisting data?

     

    This is what I have right now:

    			WorldInfo info = w.getWorldInfo();
    			NBTTagCompound modNBT = (NBTTagCompound) info.getAdditionalProperty(SlippWorld.NAME);
    
    			if(modNBT == null) {
    				Map<String, NBTBase> map = new HashMap<String, NBTBase>();
    				map.put(SlippWorld.NAME, new NBTTagCompound());
    				info.setAdditionalProperties(map);
    			}
    
    			modNBT = (NBTTagCompound) info.getAdditionalProperty(SlippWorld.NAME);

     

    Yet when I run it and try to access the modNBT variable it triggers an NPE.

  14. On 3/5/2017 at 1:52 AM, Draco18s said:

     

    On 3/6/2017 at 8:26 AM, OreCruncher said:

    Look here.  But if you are looking for a general version check to notify the player of a new version I would suggest you use the Forge API as Draco indicates above.

    I'm aware of this but I'm asking about using the curse mod page to automatically generate a list of versions rather than creating one myself.

  15. 13 minutes ago, Lhykos said:

    I think you call a client method in your "onMessage" method in the handler class.

    Can you post the code of you "MessageSyncClientHandler" class?

    http://pastebin.com/0FXgPP5C

     

    I'm not sure how I would accomplish this without referencing the player. I was thinking about having a static class that would just hold the items in a field so that it won't have to reference any piece of Minecraft at all, but that seems hacky.

  16. I'm receiving this error when trying to host a server with a built version of my mod (quickconsume):

     

    ---- Minecraft Crash Report ----

    WARNING: coremods are present:
      FMLPlugin (InventoryTweaks-1.62-dev-77.jar)
      LoadingPlugin (Quark-r1.2-81.jar)
      AppleCore (AppleCore-mc1.11.2-2.1.1.jar)
      IvToolkit (IvToolkit-1.3.2.1.jar)
    Contact their authors BEFORE contacting forge

    // I'm sorry, Dave.

    Time: 2/25/17 1:27 PM
    Description: Exception in server tick loop

    net.minecraftforge.fml.common.LoaderExceptionModCrash: Caught exception from Quick Consume (quickconsume)
    Caused by: java.lang.NoClassDefFoundError: net/minecraft/client/entity/EntityPlayerSP
        at java.lang.Class.getDeclaredConstructors0(Native Method)
        at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
        at java.lang.Class.getConstructor0(Class.java:3075)
        at java.lang.Class.newInstance(Class.java:412)
        at net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper.instantiate(SimpleNetworkWrapper.java:171)
        at net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper.registerMessage(SimpleNetworkWrapper.java:164)
        at com.kain.quickconsume.proxy.CommonProxy.init(CommonProxy.java:28)
        at com.kain.quickconsume.QuickConsume.preInit(QuickConsume.java:30)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at net.minecraftforge.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:641)
        at sun.reflect.GeneratedMethodAccessor8.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)
        at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47)
        at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)
        at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)
        at com.google.common.eventbus.EventBus.post(EventBus.java:275)
        at net.minecraftforge.fml.common.LoadController.sendEventToModContainer(LoadController.java:246)
        at net.minecraftforge.fml.common.LoadController.propogateStateMessage(LoadController.java:224)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)
        at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47)
        at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)
        at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)
        at com.google.common.eventbus.EventBus.post(EventBus.java:275)
        at net.minecraftforge.fml.common.LoadController.distributeStateMessage(LoadController.java:147)
        at net.minecraftforge.fml.common.Loader.preinitializeMods(Loader.java:628)
        at net.minecraftforge.fml.server.FMLServerHandler.beginServerLoading(FMLServerHandler.java:100)
        at net.minecraftforge.fml.common.FMLCommonHandler.onServerStart(FMLCommonHandler.java:331)
        at net.minecraft.server.dedicated.DedicatedServer.func_71197_b(DedicatedServer.java:121)
        at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:442)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: java.lang.ClassNotFoundException: net.minecraft.client.entity.EntityPlayerSP
        at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:191)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 39 more
    Caused by: net.minecraftforge.fml.common.asm.ASMTransformerWrapper$TransformerException: Exception in class transformer net.minecraftforge.fml.common.asm.transformers.SideTransformer@3ecd267f from coremod FMLCorePlugin
        at net.minecraftforge.fml.common.asm.ASMTransformerWrapper$TransformerWrapper.transform(ASMTransformerWrapper.java:257)
        at net.minecraft.launchwrapper.LaunchClassLoader.runTransformers(LaunchClassLoader.java:279)
        at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:176)
        ... 41 more
    Caused by: java.lang.RuntimeException: Attempted to load class bps for invalid side SERVER
        at net.minecraftforge.fml.common.asm.transformers.SideTransformer.transform(SideTransformer.java:56)
        at net.minecraftforge.fml.common.asm.ASMTransformerWrapper$TransformerWrapper.transform(ASMTransformerWrapper.java:253)
        ... 43 more


    A detailed walkthrough of the error, its code path and all known details is as follows:
    ---------------------------------------------------------------------------------------

    -- System Details --
    Details:
        Minecraft Version: 1.11.2
        Operating System: Windows 10 (amd64) version 10.0
        Java Version: 1.8.0_65, Oracle Corporation
        Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
        Memory: 113158624 bytes (107 MB) / 284000256 bytes (270 MB) up to 2112618496 bytes (2014 MB)
        JVM Flags: 2 total; -Xincgc -Xmx2G
        IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
        FML: MCP 9.38 Powered by Forge 13.20.0.2228 30 mods loaded, 30 mods active
        States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored
        UCH    minecraft{1.11.2} [Minecraft] (minecraft.jar) 
        UCH    mcp{9.19} [Minecraft Coder Pack] (minecraft.jar) 
        UCH    FML{8.0.99.99} [Forge Mod Loader] (forge-1.11.2-13.20.0.2228-universal.jar) 
        UCH    forge{13.20.0.2228} [Minecraft Forge] (forge-1.11.2-13.20.0.2228-universal.jar) 
        UCH    ivtoolkit{1.3.2.1} [IvToolkit] (minecraft.jar) 
        UCH    actuallyadditions{1.11.2-r102} [Actually Additions] (ActuallyAdditions-1.11.2-r102.jar) 
        UCH    applecore{2.1.1} [AppleCore] (AppleCore-mc1.11.2-2.1.1.jar) 
        UCH    quark{r1.2-81} [Quark] (Quark-r1.2-81.jar) 
        UCH    autoreglib{1.1-4} [AutoRegLib] (AutoRegLib-1.1-4.jar) 
        UCH    betterachievements{0.4.3.12} [Better Achievements] (BetterAchievements-1.11.2-0.4.3.12.jar) 
        UCH    cfm{4.1.2} [MrCrayfish's Furniture Mod] (cfm-4.1.2-mc1.11.2.jar) 
        UCH    chiselsandbits{13.10} [Chisels & Bits] (chiselsandbits-13.10.jar) 
        UCH    cookingforblockheads{5.2.6} [Cooking for Blockheads] (CookingForBlockheads_1.11.2-5.2.6.jar) 
        UCH    dldungeonsjdg{1.9.0} [Doomlike Dungeons] (DoomlikeDungeons-1.9.1-MC1.11.2.jar) 
        UCH    enderthing{0.7.3} [Enderthing] (enderthing-1.11.0-0.7.3.jar) 
        UCH    gravestone{1.7.2} [Gravestone] (GraveStone Mod 1.7.2.jar) 
        UCH    inventorytweaks{1.62-dev-77-7812cce} [Inventory Tweaks] (InventoryTweaks-1.62-dev-77.jar) 
        UCH    jei{4.2.7.240} [Just Enough Items] (jei_1.11.2-4.2.7.240.jar) 
        UCH    journeymap{1.11.2-5.4.6} [JourneyMap] (journeymap-1.11.2-5.4.6.jar) 
        UCE    quickconsume{1.1} [Quick Consume] (modid-1.0.jar) 
        UCH    harvestcraft{1.11.2d} [Pam's HarvestCraft] (Pam's HarvestCraft 1.11.2d.jar) 
        UCH    persistentbits{1.0.6} [Persistent Bits] (PersistentBits-1.11-1.0.6.jar) 
        UCH    reccomplex{1.2.9.1} [Recurrent Complex] (RecurrentComplex-1.2.9.1.jar) 
        UCH    refinedstorage{1.4.1} [Refined Storage] (refinedstorage-1.4.1.jar) 
        UCH    xreliquary{1.11.2-1.3.3.635} [Reliquary] (Reliquary-1.11.2-1.3.3.635.jar) 
        UCH    roguelike{1.6.3} [Roguelike Dungeons] (RoguelikeDungeons-1.11.2-1.6.3.jar) 
        UCH    lteleporters{1.11.2-2.0.2} [Simple Teleporters] (SimpleTeleporters-1.11.2-2.0.2.jar) 
        UCH    simplyconveyors{2.1.0} [Simply Conveyors] (SimplyConveyors-2.1.2.jar) 
        UCH    soulshardstow{1.11-2.6.6-47} [Soul Shards - The Old Ways] (SoulShards-TOW-1.11-2.6.6-47.jar) 
        UCH    usefulnullifiers{1.3.4} [Useful Nullifiers] (usefulnullifiers-1.3.4.jar) 
        Loaded coremods (and transformers): 
    FMLPlugin (InventoryTweaks-1.62-dev-77.jar)
      invtweaks.forge.asm.ContainerTransformer
    LoadingPlugin (Quark-r1.2-81.jar)
      vazkii.quark.base.asm.ClassTransformer
    AppleCore (AppleCore-mc1.11.2-2.1.1.jar)
      squeek.applecore.asm.TransformerModuleHandler
    IvToolkit (IvToolkit-1.3.2.1.jar)
      
        Profiler Position: N/A (disabled)
        Is Modded: Definitely; Server brand changed to 'fml,forge'
        Type: Dedicated Server (map_server.txt)

     

    Here's the class in question: http://pastebin.com/hqGR6Cjm

    The purpose of the MessageSyncClient class is to be sent from the server to the client, so it has to be registered on the server side. I'm not sure why it's referencing EntityPlayerSP too.

  17. I have a "recipe" where a player can right click a full cauldron that has 2 entity items in it to create 1 entity item as a product. It consumes 2 gold nuggets and 1 healing potion I or 2 gold ingots and 1 healing potion II.

     

    The problem right now is presented below:

    2 gold nuggets + 1 healing potion I = 1 healing potion

    2 gold ingots + 1 healing potion II = 1 greater healing potion

    4 gold nuggets + 1 healing potion I = 2 healing potions

    4 gold ingots + 1 healing potion II = 2 greater healing potions

    6 gold nuggets + 1 healing potion I = 2 healing potions (remainder of 2 gold nuggets)

    6 gold ingots + 1 healing potion II = 2 greater healing potions (remainder of 2 gold ingots)

     

    The problematic results are bolded.

     

    Code:

        @SubscribeEvent
        public void playerInteract(PlayerInteractEvent.RightClickBlock ev) {
            EntityPlayer p = ev.getEntityPlayer();

            if(!p.world.isRemote) {
                if(p.world.getBlockState(ev.getPos()).getBlock() == Blocks.CAULDRON) {
                    if(p.world.getBlockState(ev.getPos()).getValue(BlockCauldron.LEVEL).intValue() == 3) {
                        if(p.getHeldItemMainhand().getItem() == Items.STICK) {
                            List<EntityItem> entities = p.world.getEntitiesWithinAABB(EntityItem.class, new AxisAlignedBB(ev.getPos()));
                            EntityItem goldNE = null, goldE = null, potion1E = null, potion2E = null;

                            for(EntityItem ei : entities) {
                                ItemStack is = ei.getEntityItem();
                                Item i = is.getItem();

                                if(i == Items.GOLD_NUGGET) {
                                    if(is.getCount() >= 2) {
                                        goldNE = ei;
                                    }
                                } else if(i == Items.GOLD_INGOT) {
                                    if(is.getCount() >= 2) {
                                        goldE = ei;
                                    }
                                } else if(i == Items.POTIONITEM) {
                                    ItemPotion pot = (ItemPotion) i;
                                    List<PotionEffect> effects = PotionUtils.getEffectsFromStack(is);

                                    for(PotionEffect eff : effects) {
                                        if(eff.getPotion() == Potion.getPotionById(6)) { //TODO: make config to change instant health potion ID
                                            if(eff.getAmplifier() == 0) {
                                                potion1E = ei;
                                            } else if(eff.getAmplifier() == 1) {
                                                potion2E = ei;
                                            }
                                        }
                                    }
                                }
                            }

                            if(goldNE != null && potion1E != null) {
                                goldNE.getEntityItem().shrink(2);

                                EntityItem newPot = new EntityItem(p.world, potion1E.posX, potion1E.posY, potion1E.posZ, new ItemStack(QuickConsume.healing_potion, 1)); //PRODUCT 1
                                p.world.spawnEntity(newPot);
                                p.world.removeEntity(potion1E);
                                
                                return;
                            }

                            if(goldE != null && potion2E != null) {
                                goldE.getEntityItem().shrink(2);

                                EntityItem newPot = new EntityItem(p.world, potion2E.posX, potion2E.posY, potion2E.posZ, new ItemStack(QuickConsume.greater_healing_potion, 1)); //PRODUCT 2
                                p.world.spawnEntity(newPot);
                                p.world.removeEntity(potion2E);
                                
                                return;
                            }
                        }
                    }
                }
            }
        }

  18. 51 minutes ago, diesieben07 said:

    First of all, stop using getEntityData. It has been replaced by  better system twice over already. First IExtendedEntityProperties, now capabilities.

    Both allow you to actually store stuff attached to the player and don't force you to constantly serialize to and from NBT.

    Ok, I've switched over to the capability system. Is there a way of synchronizing the capabilities with the client? It doesn't seem to at the moment.

  19. I have itemstacks stored inside of the player's NBTTagCompound on the server side, but I want to render the items on the client side. As far as I know, the player's NBTTagCompound isn't synced automatically, so my issue is how to send the NBTTagCompound or ItemStacks to the client from the server.

     

    I've tried looking online for solutions, but I only found articles regarding the old Packet system using CompressedStreamTools. I'm currently using the SimpleNetworkWrapper with classes implementing IMessage; is there anyway to input the ByteBuf as a stream object that can be used with CompressedStreamTools?

     

    Another solution I tried was finding a way to compress an NBTTagCompound or a NonNullList into a byte array, but I haven't found any methods yet.

     

    I'm not sure how to provide code for this, but here's how I'm storing the ItemStacks on the server:

     

            ...

            NBTTagCompound nbt = player.getEntityData();
            NBTTagCompound isNBT = nbt.getCompoundTag(QuickConsume.KEY);
            NonNullList<ItemStack> items = NonNullList.<ItemStack> withSize(3, ItemStack.EMPTY);
            ItemStackHelper.loadAllItems(isNBT, items);

            ...
            ItemStackHelper.saveAllItems(isNBT, items);
            nbt.setTag(QuickConsume.KEY, isNBT);

  20. I'm having a lot of trouble trying to render a basic item. The console says nothing about the item texture and in-game the item renders as a block textured with the purple and black squares.

     

    Mod:

     

    package tlhpoe.bonanzas;
    
    import net.minecraft.block.*;
    import net.minecraft.creativetab.*;
    import net.minecraft.item.*;
    import net.minecraftforge.fml.common.*;
    import net.minecraftforge.fml.common.Mod.*;
    import net.minecraftforge.fml.common.event.*;
    
    @Mod(modid = Bonanzas.MODID, version = Bonanzas.VERSION)
    public class Bonanzas {
    public static final String MODID = "bonanzas";
    public static final String VERSION = "1.0.0";
    
    @Instance(MODID)
    public static Bonanzas instance;
    
    @SidedProxy(serverSide = "tlhpoe.bonanzas.CommonProxy", clientSide = "tlhpoe.bonanzas.ClientProxy")
    public static CommonProxy proxy;
    
    @EventHandler
    public void preInit(FMLPreInitializationEvent event) {
    	proxy.initServer(event);
    	proxy.initClient(event);
    }
    
    @EventHandler
    public void init(FMLInitializationEvent event) {
    	proxy.initServer(event);
    	proxy.initClient(event);
    }
    
    @EventHandler
    public void postInit(FMLPostInitializationEvent event) {
    	proxy.initServer(event);
    	proxy.initClient(event);
    }
    
    public static class Items {
    	public static Item ingotMod = new Item().setUnlocalizedName("ingotMod").setCreativeTab(CreativeTabs.FOOD);
    	public static Block ore;
    }
    }
    

     

     

    CommonProxy:

     

    package tlhpoe.bonanzas;
    
    import net.minecraft.util.*;
    import net.minecraftforge.fml.common.event.*;
    import net.minecraftforge.fml.common.registry.*;
    
    public class CommonProxy {
    public void initServer(FMLStateEvent state) {
    	if(state instanceof FMLPreInitializationEvent) {
    		registerItems();
    	}
    }
    
    public void initClient(FMLStateEvent state) {
    }
    
    private static void registerItems() {
    	GameRegistry.register(Bonanzas.Items.ingotMod, new ResourceLocation(Bonanzas.MODID + ":" + Bonanzas.Items.ingotMod.getUnlocalizedName().substring(5)));
    }
    }
    

     

     

    ClientProxy:

     

    package tlhpoe.bonanzas;
    
    import net.minecraft.client.*;
    import net.minecraft.client.renderer.block.model.*;
    import net.minecraft.item.*;
    import net.minecraftforge.client.model.*;
    import net.minecraftforge.fml.common.event.*;
    
    public class ClientProxy extends CommonProxy {
    @Override
    public void initClient(FMLStateEvent state) {
    	if(state instanceof FMLInitializationEvent) {
    		registerItems();
    	}
    }
    
    private static void registerItems() {
    	registerItemRenderer(Bonanzas.Items.ingotMod);
    }
    
    private static void registerItemRenderer(Item item) {
    	ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(Bonanzas.MODID + ":" + item.getUnlocalizedName().substring(5)));
    }
    }
    

     

     

    ingotMod.json:

     

    {
        "parent": "item/generated",
        "textures": {
            "layer0": "bonanzas:items/ingotMod"
        }
    }
    

     

     

    File Hierarchy:

     

    22fbcfb013504eb2b127689c00557fa1.png

     

×
×
  • Create New...

Important Information

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