TLHPoE
-
Posts
638 -
Joined
-
Last visited
Posts posted by TLHPoE
-
-
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.
-
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):
Spoilerpackage 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" } }
-
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:
SpoilerAnimalium 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.
-
18 hours ago, Choonster said:
I can't see any obvious issues with your code, could you create a Git repository for it (if you don't already have one) and link it here? I'll try debugging it myself.
https://github.com/phan-kavin/SlippWorld
Forge version 1.11.2-13.20.0.2228
-
2 hours ago, Jay Avery said:
So what exactly tells you that the cool down is not being set to 100?
This check:
if(data != null && data.getCoolDown() == 0) {
This passes every time, and inside the clause it sets the cool down to 100.
- 1
-
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.
-
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.
-
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.
-
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; } }
-
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?
-
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.
-
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.
-
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.
-
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.
-
On 3/5/2017 at 1:52 AM, Draco18s said:
Bad modder, no cookie.
https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/
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.
-
Is there anyway to retrieve all downloads of a mod on the curseforge website? Specifically for detecting if the instance of the mod is outdated? Or should I just stay with manually setting the latest version in a text file?
-
If I build my mod for each major version (1.7, 1.8, 1.9, 1.10, 1.11), will it be able to run on its sub-versions (1.7.2, 1.7.10, 1.9.4, 1.10.2, etc)?
-
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?
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.
-
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 loopnet.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.
-
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;
}
}
}
}
}
} -
5 minutes ago, diesieben07 said:
You send packets.
I realize this, but in the fromBytes and toBytes methods, how do I convert the ItemStacks to bytes? I asked this question in the original post as well.
-
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.
-
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); -
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:
[1.12.2] Dynamic Recipes
in Modder Support
Posted
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.