Jump to content

Recommended Posts

Posted

Ok this is a big one, but it's important.

 

I would really like to know how I can create an object, that checks what items are dropped into it, put that into some sort of list, compare a it to another list (containing a recipe), then if the lists match, I want it to output a specific item. Here is my current code for the Tile Entity, and the Recipes Class that have all the recipes in it (currently there is only one for testing purposes) Thanks and would really appreciate an explanation on how to do this, and if my explanation of doing this is wrong, then please correct me. (Yes I know java, its just that I have bare bones knowledge of the Forge API and have no idea what im really doing in that context, learning is my ultimate goal here so please help me out!) Thanks.

 

TileEntity

Spoiler

package emeraldjelly.mystica.blocks.tileentity;

import emeraldjelly.mystica.util.recipe.CauldronRecipe;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EntitySelectors;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraftforge.items.ItemStackHandler;

import java.util.ArrayList;
import java.util.List;

public class TileEntitySorcerersCauldron extends TileEntity implements ITickable {

    public static AxisAlignedBB AABB = new AxisAlignedBB(0, 0, 0, 1, 1.2D, 1);

    private int cooldown;
    private ItemStackHandler handler;

    public TileEntitySorcerersCauldron() {
        this.cooldown = 0;
        this.handler = new ItemStackHandler(5);
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        compound.setInteger("Cooldown", this.cooldown);
        compound.setTag("ItemStackHandler", this.handler.serializeNBT());
        return super.writeToNBT(compound);
    }

    @Override
    public void readFromNBT(NBTTagCompound compound) {
        this.cooldown = compound.getInteger("Cooldown");
        this.handler.deserializeNBT(compound.getCompoundTag("ItemStackHandler"));
        super.readFromNBT(compound);
    }

    @Override
    public void update() {
        this.cooldown++;
        this.cooldown %= 100;
    }

    public static List<EntityItem> getCaptureItems(World worldIn) {
        return worldIn.<EntityItem>getEntitiesWithinAABB(EntityItem.class, AABB, EntitySelectors.IS_ALIVE);
    }

    @Override
    public SPacketUpdateTileEntity getUpdatePacket() {
        NBTTagCompound nbt = new NBTTagCompound();
        this.writeToNBT(nbt);
        int metadata = getBlockMetadata();
        return new SPacketUpdateTileEntity(this.pos, metadata, nbt);
    }

    @Override
    public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
        this.readFromNBT(pkt.getNbtCompound());
    }

    @Override
    public NBTTagCompound getUpdateTag() {
        NBTTagCompound nbt = new NBTTagCompound();
        this.writeToNBT(nbt);
        return nbt;
    }

    @Override
    public void handleUpdateTag(NBTTagCompound tag) {
        this.readFromNBT(tag);
    }

    @Override
    public NBTTagCompound getTileData() {
        NBTTagCompound nbt = new NBTTagCompound();
        this.writeToNBT(nbt);
        return nbt;
    }
}

 

 

CauldronRecipes

Spoiler

package emeraldjelly.mystica.util.recipe;

import emeraldjelly.mystica.init.ModItems;
import net.minecraft.item.ItemStack;

import java.util.ArrayList;
import java.util.Arrays;

public class CauldronRecipes {

    public static final ArrayList<ItemStack> SNOWBALL = new ArrayList(Arrays.asList(ModItems.EMPTYLACRAMA, ModItems.EMPTYLACRAMA));

}

 

 

BlockClass

Spoiler

package emeraldjelly.mystica.blocks;

import emeraldjelly.mystica.blocks.tileentity.TileEntitySorcerersCauldron;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;


public class SorcerersCauldron extends BlockBase implements ITileEntityProvider {

    public SorcerersCauldron(String name, Material material) {
        super(name, material);
        setHardness(3F);
        setResistance(3F);
        setHarvestLevel("pickaxe", 3);
    }

    @Override
    public TileEntity createNewTileEntity(World worldIn, int meta) {
        return new TileEntitySorcerersCauldron();
    }

}

 

 

  • Replies 67
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted Images

Posted

Do you want a GUI where player puts these items into slots, or do you want to be able to just "drop" or throw items near it? It seems that you are trying to do the latter...

 

If you don't want a GUI, then you're on the right track. Doesn't look like you need much help. I think you just need to take the EntityItems that you find and check if you have everything needed for the recipe and if that is true then "kill" the ingredient EntityItems and spawn the result EntityItem.

 

If you do want a GUI then basically you're making a crafting table and you can check out tutorials and other mods' for such things. But the main thing is it is recommended in that case to use the Container and GuiHandler system to help sync things up.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted (edited)

Yeah im going for just dropping the item, but can you give me an example on how I would go around doing this? What I've tried never seems to work :( (I deleted the code for the broken things I have done so I can't share that with you. Dont really know how I can get it back)

 

EDIT: Here is what I tried. I can you tell me if this is good, or what should I change?

 

Spoiler

package emeraldjelly.mystica.blocks.tileentity;

import emeraldjelly.mystica.util.recipe.CauldronRecipes;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EntitySelectors;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraftforge.items.ItemStackHandler;

import java.util.ArrayList;
import java.util.List;

public class TileEntitySorcerersCauldron extends TileEntity implements ITickable {

    public static AxisAlignedBB AABB = new AxisAlignedBB(0, 0, 0, 1, 1.2D, 1);

    private int cooldown;
    private ItemStackHandler handler;

    public TileEntitySorcerersCauldron() {
        this.cooldown = 0;
        this.handler = new ItemStackHandler(5);
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        compound.setInteger("Cooldown", this.cooldown);
        compound.setTag("ItemStackHandler", this.handler.serializeNBT());
        return super.writeToNBT(compound);
    }

    @Override
    public void readFromNBT(NBTTagCompound compound) {
        this.cooldown = compound.getInteger("Cooldown");
        this.handler.deserializeNBT(compound.getCompoundTag("ItemStackHandler"));
        super.readFromNBT(compound);
    }

    @Override
    public void update() {
        this.cooldown++;
        this.cooldown %= 100;
        checkWithCauldronRecipe(getItemStackArrayListFromCaptured(getCaptureItems(world)));
    }

    public static List<EntityItem> getCaptureItems(World worldIn) {
        return worldIn.<EntityItem>getEntitiesWithinAABB(EntityItem.class, AABB, EntitySelectors.IS_ALIVE);
    }

    public static ArrayList<ItemStack> getItemStackArrayListFromCaptured(List<EntityItem> items) {
        ArrayList<ItemStack> ist = new ArrayList<>();
        for (int i = 0; i < items.size(); i++) {
            EntityItem item = items.get(0);
            Item cI = item.getItem().getItem();
            ItemStack stack = new ItemStack(cI);
            ist.add(stack);
        }
        return ist;
    }

        public boolean checkWithCauldronRecipe(ArrayList<ItemStack> stacks) {
        int count = 0;
        for (int i = 0; i < stacks.size(); i++) {
            if (stacks.get(1) == CauldronRecipes.SNOWBALL.get(i)) {
                count++;
            }
        }
        if (count == stacks.size()) {
            craft();
            return true;
        }
        return false;
    }

    public void craft() {
        EntityPlayer player = Minecraft.getMinecraft().player;
        World world = Minecraft.getMinecraft().player.getEntityWorld();
        InventoryHelper.spawnItemStack(world, player.getPosition().getX(), player.getPosition().getY(), player.getPosition().getZ(), CauldronRecipes.SNOWBALL_OUT);
    }

    @Override
    public SPacketUpdateTileEntity getUpdatePacket() {
        NBTTagCompound nbt = new NBTTagCompound();
        this.writeToNBT(nbt);
        int metadata = getBlockMetadata();
        return new SPacketUpdateTileEntity(this.pos, metadata, nbt);
    }

    @Override
    public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
        this.readFromNBT(pkt.getNbtCompound());
    }

    @Override
    public NBTTagCompound getUpdateTag() {
        NBTTagCompound nbt = new NBTTagCompound();
        this.writeToNBT(nbt);
        return nbt;
    }

    @Override
    public void handleUpdateTag(NBTTagCompound tag) {
        this.readFromNBT(tag);
    }

    @Override
    public NBTTagCompound getTileData() {
        NBTTagCompound nbt = new NBTTagCompound();
        this.writeToNBT(nbt);
        return nbt;
    }
}

 

 

Spoiler

package emeraldjelly.mystica.util.recipe;

import emeraldjelly.mystica.init.ModItems;
import net.minecraft.client.Minecraft;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;

import java.util.ArrayList;
import java.util.Arrays;

public class CauldronRecipes {

    public static final ArrayList<ItemStack> SNOWBALL = new ArrayList(Arrays.asList(ModItems.EMPTYLACRAMA, ModItems.EMPTYLACRAMA));

    public static final ItemStack SNOWBALL_OUT = new ItemStack(Item.getItemById(332));

}

 

 

Edited by EmeraldJelly
Posted

If you want a block to pick up dropped items, look at the Hopper.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted (edited)

I did that is where I got the getCapturedItems thing, but it stores it into an inventory. I do not want to do that, I just wanna compare it to a recipe ArrayList of itemstacks.

 

What I did just crashes my game with THIS Console Error:

 

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

-- Head --
Thread: Client thread
Stacktrace:
	at emeraldjelly.mystica.blocks.tileentity.TileEntitySorcerersCauldron.craft(TileEntitySorcerersCauldron.java:89)
	at emeraldjelly.mystica.blocks.tileentity.TileEntitySorcerersCauldron.checkWithCauldronRecipe(TileEntitySorcerersCauldron.java:80)
	at emeraldjelly.mystica.blocks.tileentity.TileEntitySorcerersCauldron.update(TileEntitySorcerersCauldron.java:53)

-- Block entity being ticked --
Details:
	Name: myt:sorcerers_cauldron // emeraldjelly.mystica.blocks.tileentity.TileEntitySorcerersCauldron
	Block type: ID #259 (tile.sorcerers_cauldron // emeraldjelly.mystica.blocks.SorcerersCauldron)
	Block data value: 0 / 0x0 / 0b0000
	Block location: World: (1352,237,207), Chunk: (at 8,14,15 in 84,12; contains blocks 1344,0,192 to 1359,255,207), Region: (2,0; contains chunks 64,0 to 95,31, blocks 1024,0,0 to 1535,255,511)
	Actual block type: ID #259 (tile.sorcerers_cauldron // emeraldjelly.mystica.blocks.SorcerersCauldron)
	Actual block data value: 0 / 0x0 / 0b0000
Stacktrace:
	at net.minecraft.world.World.updateEntities(World.java:2004)
	at net.minecraft.world.WorldServer.updateEntities(WorldServer.java:643)

-- Affected level --
Details:
	Level name: TestFire World
	All players: 0 total; []
	Chunk stats: ServerChunkCache: 625 Drop: 0
	Level seed: -6876014066799134505
	Level generator: ID 01 - flat, ver 0. Features enabled: false
	Level generator options: 3;minecraft:bedrock,230*minecraft:stone,5*minecraft:dirt,minecraft:grass;3;biome_1,decoration,stronghold,mineshaft,dungeon
	Level spawn location: World: (1276,4,173), Chunk: (at 12,0,13 in 79,10; contains blocks 1264,0,160 to 1279,255,175), Region: (2,0; contains chunks 64,0 to 95,31, blocks 1024,0,0 to 1535,255,511)
	Level time: 132657 game time, 51330 day time
	Level dimension: 0
	Level storage version: 0x04ABD - Anvil
	Level weather: Rain time: 1 (now: false), thunder time: 1 (now: false)
	Level game mode: Game mode: creative (ID 1). Hardcore: false. Cheats: true
Stacktrace:
	at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:840)
	at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:741)
	at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:192)
	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:590)
	at java.lang.Thread.run(Thread.java:748)

-- System Details --
Details:
	Minecraft Version: 1.12.2
	Operating System: Mac OS X (x86_64) version 10.13.3
	Java Version: 1.8.0_151, Oracle Corporation
	Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
	Memory: 717653568 bytes (684 MB) / 1008730112 bytes (962 MB) up to 1908932608 bytes (1820 MB)
	JVM Flags: 0 total; 
	IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
	FML: MCP 9.42 Powered by Forge 14.23.2.2640 5 mods loaded, 5 mods active
	States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored

	| State     | ID        | Version      | Source                           | Signature |
	|:--------- |:--------- |:------------ |:-------------------------------- |:--------- |
	| UCHIJAAAA | minecraft | 1.12.2       | minecraft.jar                    | None      |
	| UCHIJAAAA | mcp       | 9.42         | minecraft.jar                    | None      |
	| UCHIJAAAA | FML       | 8.0.99.99    | forgeSrc-1.12.2-14.23.2.2640.jar | None      |
	| UCHIJAAAA | forge     | 14.23.2.2640 | forgeSrc-1.12.2-14.23.2.2640.jar | None      |
	| UCHIJAAAA | myt       | a0.1         | Mystica_main                     | None      |

	Loaded coremods (and transformers): 
	GL info: ~~ERROR~~ RuntimeException: No OpenGL context found in the current thread.
	Profiler Position: N/A (disabled)
	Player Count: 0 / 8; []
	Type: Integrated Server (map_client.txt)
	Is Modded: Definitely; Client brand changed to 'fml,forge'
[15:44:23] [main/INFO] [STDOUT]: [net.minecraft.init.Bootstrap:printToSYSOUT:629]: #@!@# Game crashed! Crash report saved to: #@!@# ./crash-reports/crash-2018-04-03_15.44.21-server.txt
[15:44:23] [Client Shutdown Thread/INFO] [net.minecraft.server.MinecraftServer]: Stopping server
[15:44:23] [Client Shutdown Thread/INFO] [net.minecraft.server.MinecraftServer]: Saving players
[15:44:23] [Client Shutdown Thread/INFO] [net.minecraft.server.MinecraftServer]: Saving worlds
AL lib: (EE) alc_cleanup: 1 device not closed

 

Edited by EmeraldJelly
Posted

Look at how shapeless recipes work for that part.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted (edited)

Don't they use JSON files?? Tell me where I can find an example in the code. But I would prefer if you can tell me what I did wrong in my code please. 

Edited by EmeraldJelly
Posted (edited)
7 minutes ago, EmeraldJelly said:

Don't they use JSON files?? Tell me where I can find an example in the code. But I would prefer if you can tell me what I did wrong in my code please. 

That's not the point. You want to know how to compare a list of items (a shapeless recipe) to another list of items (what's in the container) in order to generate a result.

JSON files are just data, you already have data. What you want is the operational code that operates on the data: the code that is in ShapelessRecipie.java

Edited by Draco18s

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted (edited)

ShapelessRecipes.Java does that in a completely different way. A. basically half the class is talking about JSON (I Know I have the data, but still the comparison it draws in their methods do not match my goals at all.. it checks if its simple, looks at inventories and such. The matches method only does comparison based on inventories.) That is not what Im trying to achieve.

 

lll break it down. I guess...

 

1. Drop item into cauldron.

2. Remove that item from world (despawn it).

2. Add item to a list.

3. Keep checking if that list matches some sort of static final recipe list.

4. Clear the list.

5. Spawn the output item in the world at player's position.

 

Ultimately: I want to create a method that checks the items thrown with a LIST of all recipes, if the items thrown in matches any recipe, output the item that the recipe matches.

 

I have tried to achieve that in my code but it crashes the game. Looking at Vanilla files doesn't help me that much because there is Nothing in vanilla Minecraft that does what I am doing. Sure, hoppers check for items, I copied that code, and it does not work. Shapeless recipes compare inventories and such to a json... I am not trying to do that. So what possibly can I do to make this work?

Edited by EmeraldJelly
Posted (edited)
37 minutes ago, EmeraldJelly said:

ShapelessRecipes.Java does that in a completely different way. A. basically half the class is talking about JSON

You haven't even looked at the class, have you?

Take a look at the matches method (link is a custom recipe, but its still shapeless). None of that code deals with JSON data files*, especially not matches. Look at what it does. Look at how it does it. Ask yourself, "is this methodology suitable for solving my problem?"

 

*The code that deals with JSON files is actually ShapelessRecipe.Factory, which is a completely different class. It's just in the same file.

Edited by Draco18s

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Step 1: create a list.

Step 2: populate it with the desired items to match against.

Step 3: for each item in the block's contents (crafting grids are 3x3, your container will just be a list), do something.

Step 4: for each item in the list created in steps 1 and 2, do something.

Step 5: do the the items match?

Step 6: if they do, remove from the list.

Step 7: if they don't, return false, there's something extra.

Step 8: the loops are complete, are there any items not found?

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted (edited)
Spoiler

package emeraldjelly.mystica.api;

import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;

import java.util.List;

public interface ICauldronRecipe {

    static boolean matches(List<ItemStack> itemStacks) {
        for (int i = 0; i < itemStacks.size(); i++) {
            ItemStack itemstack = itemStacks.get(i);
            if (itemstack != ItemStack.EMPTY) {
                boolean flag = false;

                for (ItemStack itemstack1 : itemStacks) {
                    if (!itemstack.hasTagCompound() && itemstack.getItem() == itemstack1.getItem() && (
                            itemstack1.getMetadata() == OreDictionary.WILDCARD_VALUE ||
                                    itemstack.getMetadata() == itemstack1.getMetadata())) {
                        flag = true;
                        itemStacks.remove(itemstack1);
                        break;
                    }
                }
                if (!flag) {
                    return false;
                }
            }
        }
        return itemStacks.isEmpty();
    }
}

 

^^ Matches Method

 

 

Spoiler

package emeraldjelly.mystica.util.recipe.cauldron;

import emeraldjelly.mystica.init.ModItems;
import emeraldjelly.mystica.util.recipe.recipetypes.CauldronRecipe;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;

import java.util.Arrays;
import java.util.List;

public class CauldronRecipeSnowball extends CauldronRecipe {

    public CauldronRecipeSnowball(List<Item> items, ItemStack output) {
        super(items, output);
    }

    public static final List<Item> RECIPE = Arrays.asList(ModItems.LACRAMITESHARDS, ModItems.LACRAMITESHARDS);

    public static void init() {
        addRecipe(RECIPE, new ItemStack(Item.getItemById(332)));
    }

    public static void addRecipe(List<Item> items, ItemStack output) {
        for (int i = 0; i < items.size(); i++) {
            CauldronRecipe.recipesIn.add(0, new ItemStack(items.get(i)));
        }
        CauldronRecipe.recipesOut.add(output);
    }

}

 

^^ Recipe for snowball

 

Spoiler

package emeraldjelly.mystica.util.recipe.recipetypes;

import emeraldjelly.mystica.api.ICauldronRecipe;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;

import java.util.ArrayList;
import java.util.List;

public class CauldronRecipe implements ICauldronRecipe {

    public CauldronRecipe(List<Item> items, ItemStack output) {

    }

    public static List<ItemStack> recipesIn = new ArrayList<>();
    public static List<ItemStack> recipesOut = new ArrayList<>();

}

 

^^ CauldronRecipe

 

Spoiler

package emeraldjelly.mystica.blocks.tileentity;
import emeraldjelly.mystica.api.ICauldronRecipe;
import emeraldjelly.mystica.util.recipe.cauldron.CauldronRecipeSnowball;
import emeraldjelly.mystica.util.recipe.recipetypes.CauldronRecipe;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EntitySelectors;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraftforge.items.ItemStackHandler;

import java.util.ArrayList;
import java.util.List;

public class TileEntitySorcerersCauldron extends TileEntity implements ITickable, ICauldronRecipe {

    public static AxisAlignedBB AABB = new AxisAlignedBB(0, 0, 0, 1, 1.2D, 1);
    static List<ItemStack> items = new ArrayList<>();

    private int cooldown;
    private ItemStackHandler handler;

    public TileEntitySorcerersCauldron() {
        this.cooldown = 0;
        this.handler = new ItemStackHandler(5);
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        compound.setInteger("Cooldown", this.cooldown);
        compound.setTag("ItemStackHandler", this.handler.serializeNBT());
        return super.writeToNBT(compound);
    }

    @Override
    public void readFromNBT(NBTTagCompound compound) {
        this.cooldown = compound.getInteger("Cooldown");
        this.handler.deserializeNBT(compound.getCompoundTag("ItemStackHandler"));
        super.readFromNBT(compound);
    }

    @Override
    public void update() {
        this.cooldown++;
        this.cooldown %= 100;

        populateCauldronList(getCaptureItems(world));
    }

    public static List<EntityItem> getCaptureItems(World worldIn) {
        return worldIn.<EntityItem>getEntitiesWithinAABB(EntityItem.class, AABB, EntitySelectors.IS_ALIVE);
    }

    public static void populateCauldronList(List<EntityItem> entityItems) {
        for (int i = 0; i < entityItems.size(); i++) {
           items.add(new ItemStack(entityItems.get(i).getItem().getItem()));
        }
        checkAndCraft(items);
    }

    public static void checkAndCraft(List<ItemStack> itemsList) {
        if (ICauldronRecipe.matches(itemsList)) {
            //How do i know which output i need to spawn here
        }
    }

    @Override
    public SPacketUpdateTileEntity getUpdatePacket() {
        NBTTagCompound nbt = new NBTTagCompound();
        this.writeToNBT(nbt);
        int metadata = getBlockMetadata();
        return new SPacketUpdateTileEntity(this.pos, metadata, nbt);
    }

    @Override
    public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
        this.readFromNBT(pkt.getNbtCompound());
    }

    @Override
    public NBTTagCompound getUpdateTag() {
        NBTTagCompound nbt = new NBTTagCompound();
        this.writeToNBT(nbt);
        return nbt;
    }

    @Override
    public void handleUpdateTag(NBTTagCompound tag) {
        this.readFromNBT(tag);
    }

    @Override
    public NBTTagCompound getTileData() {
        NBTTagCompound nbt = new NBTTagCompound();
        this.writeToNBT(nbt);
        return nbt;
    }
}

 

^^ TileEntity Class

 

 

 

How do I get the thing to know which one to output... Do I just throw that into the matches method or what..... 

Edited by EmeraldJelly
Posted

If the recipe matches, get the recipe's output.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted (edited)

It Thinks that EVEN if there are NO ITEMS dropped anywhere near the block, it thinks that items match and constantly tries to do something. I tested this by putting down a print statement in the checkAndCraft() method.

 

 

[21:13:40] [main/INFO] [STDOUT]: [emeraldjelly.mystica.blocks.tileentity.TileEntitySorcerersCauldron:checkAndCraft:71]: Did something?
[21:13:40] [Server thread/INFO] [STDOUT]: [emeraldjelly.mystica.blocks.tileentity.TileEntitySorcerersCauldron:checkAndCraft:71]: Did something?

Edited by EmeraldJelly
Posted (edited)

Ok so

1) You need a list of recipes to check against

2) Your ICauldronRecipe interface does not contain any method for getting the result.

3) Your ICauldronRecipe is not a valid interface. Interfaces do not define methods, only declare them

4) You didn't post the crash

Edited by Draco18s

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

ugh. how. do  fix this... Please just help me fix this I've been stuck on this one stupid thing for too long. But if I understand how to do something like this, it will help understand a lot more.  flat out do not know how the hell I can do that properly. What implements what, what extends what, how do I get the dropped items to be recognized because they flat out aren't being recognized... do I just have 1 class containing public static final List<ItemStack> recipes.. I know im being really annoying and you probably want to strangle me right now (I dont blame you) but can you just talk to me like im a baby for a second...

 

 

(sorry for the damn attitude im just pissed off irl about something. can't help it.)

Posted

You know how recipes extend IRecipe and how there is a CraftingManager that knows about all the recipes that exist?

You need to mimic that.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Your TE's inventory capability.

You probably don't even need it at all, unless you plan on doing NBT data items

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted (edited)

CauldronRecipe.java

package emeraldjelly.mystica.util.recipe.recipetypes;
;
import emeraldjelly.mystica.api.ICauldronRecipe;
import emeraldjelly.mystica.init.ModItems;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class CauldronRecipe implements ICauldronRecipe { //What am  Missing in this class? Where do i make all of this code happen?

    public CauldronRecipe(List<Item> items, ItemStack output) {

    }

    private ItemStack resultItem = ItemStack.EMPTY;
    public static final List<Item> EMPTYLACRAMA = new ArrayList<>(Arrays.asList(ModItems.VERTO_PULVERIS,
            ModItems.VERTO_PULVERIS,
            ModItems.VERTO_PULVERIS,
            ModItems.VERTO_PULVERIS,
            ModItems.VERTO_PULVERIS,
            ModItems.EMPTYLACRAMA)); // Output (Always the 5th Item) <-- = resultItem.


    @Override
    public boolean matches(List<ItemStack> itemStacks) {
        for (int i = 0; i < itemStacks.size(); i++) {
            ItemStack itemstack = itemStacks.get(i);
            if (itemstack != ItemStack.EMPTY) {
                boolean flag = false;

                for (ItemStack itemstack1 : itemStacks) {
                    if (!itemstack.hasTagCompound() && itemstack.getItem() == itemstack1.getItem() && (
                            itemstack1.getMetadata() == OreDictionary.WILDCARD_VALUE ||
                                    itemstack.getMetadata() == itemstack1.getMetadata())) {
                        flag = true;
                        if (i == 4) {
                            resultItem = itemStacks.get(5);
                            break;
                        }
                        itemStacks.remove(itemstack1);
                        break;
                    }
                }
                if (!flag) {
                    return false;
                }
            }
        }
        return itemStacks.isEmpty();
    }

    @Override
    public ItemStack getCraftingResult() {
        return resultItem;
    }
}

 

 

TileEntitySorcerersCauldron.java

package emeraldjelly.mystica.blocks.tileentity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EntitySelectors;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraftforge.items.ItemStackHandler;

import java.util.ArrayList;
import java.util.List;

public class TileEntitySorcerersCauldron extends TileEntity implements ITickable { //Do i need to Implement anything else?

    public static AxisAlignedBB AABB = new AxisAlignedBB(0, 0, 0, 1, 1.2D, 1);
    static List<ItemStack> items = new ArrayList<>();

    private int cooldown;
    private ItemStackHandler handler;

    public TileEntitySorcerersCauldron() {
        this.cooldown = 0;
        this.handler = new ItemStackHandler(5);
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        compound.setInteger("Cooldown", this.cooldown);
        compound.setTag("ItemStackHandler", this.handler.serializeNBT());
        return super.writeToNBT(compound);
    }

    @Override
    public void readFromNBT(NBTTagCompound compound) {
        this.cooldown = compound.getInteger("Cooldown");
        this.handler.deserializeNBT(compound.getCompoundTag("ItemStackHandler"));
        super.readFromNBT(compound);
    }

    @Override
    public void update() {
        this.cooldown++;
        this.cooldown %= 100;

        populateCauldronList(getCaptureItems(world));
    }

    public  List<EntityItem> getCaptureItems(World worldIn) {
        return worldIn.<EntityItem>getEntitiesWithinAABB(EntityItem.class, AABB, EntitySelectors.IS_ALIVE);
    }

    public void populateCauldronList(List<EntityItem> entityItems) {
        for (int i = 0; i < entityItems.size(); i++) {
           items.add(new ItemStack(entityItems.get(i).getItem().getItem()));
        }
        checkAndCraft(items);
    }

    public void checkAndCraft(List<ItemStack> itemsList) {
        //Anything here....??
    }

    @Override
    public SPacketUpdateTileEntity getUpdatePacket() {
        NBTTagCompound nbt = new NBTTagCompound();
        this.writeToNBT(nbt);
        int metadata = getBlockMetadata();
        return new SPacketUpdateTileEntity(this.pos, metadata, nbt);
    }

    @Override
    public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
        this.readFromNBT(pkt.getNbtCompound());
    }

    @Override
    public NBTTagCompound getUpdateTag() {
        NBTTagCompound nbt = new NBTTagCompound();
        this.writeToNBT(nbt);
        return nbt;
    }

    @Override
    public void handleUpdateTag(NBTTagCompound tag) {
        this.readFromNBT(tag);
    }

    @Override
    public NBTTagCompound getTileData() {
        NBTTagCompound nbt = new NBTTagCompound();
        this.writeToNBT(nbt);
        return nbt;
    }
}

 

 

ICauldronRecipe.java

package emeraldjelly.mystica.api;

import net.minecraft.item.ItemStack;

import java.util.List;

public interface ICauldronRecipe {
    /**
     * Used to check if a recipe matches current crafting inventory
     */
    boolean matches(List<ItemStack> itemStacks);


    /**
     * Returns an Item that is the result of this recipe
     */
    ItemStack getCraftingResult();
}


// IS THERE ANYTHING ELSE REQUIRED IN HERE?

 

 

 

Check out the comments I made around the classes, tell me if anything is missing and what I should fill in please. I THINK im close but im not really sure because everything I have tried has failed.

Edited by EmeraldJelly
Posted
2 hours ago, EmeraldJelly said:

public boolean matches(List<ItemStack> itemStacks) {
    for (int i = 0; i < itemStacks.size(); i++) {
        for (ItemStack itemstack1 : itemStacks) {

 

Why are you matching a list against itself?

2 hours ago, EmeraldJelly said:

// Output (Always the 5th Item) <-- = resultItem.

You HAVE a resultItem field! Not to mention that this list is unused and shouldn't be here anyway. This is a recipe class, it's only a template, you should create a new instance and pass it a list of items and result.

 

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted
Spoiler

package emeraldjelly.mystica.util.recipe.cauldron;

import emeraldjelly.mystica.api.ICauldronRecipe;
import emeraldjelly.mystica.init.ModItems;
import emeraldjelly.mystica.util.recipe.recipetypes.CauldronRecipe;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CauldronRecipes extends CauldronRecipe implements ICauldronRecipe {
    

    public CauldronRecipes(List<Item> items, ItemStack output) {
        super(items, output);
    }

    public static final CauldronRecipe EMPTYLACRAMA = new CauldronRecipe(new ArrayList<Item>
            (Arrays.asList(ModItems.LACRAMITESHARDS, ModItems.LACRAMITESHARDS)), new ItemStack(ModItems.EMPTYLACRAMA));

    @Override
    public boolean matches(List<ItemStack> itemStacks) {
        return super.matches(itemStacks);
    }

    @Override
    public ItemStack getCraftingResult() {
        return super.getCraftingResult();
    }
}

Like That?

 

 

Spoiler

package emeraldjelly.mystica.util.recipe.recipetypes;
;
import emeraldjelly.mystica.api.ICauldronRecipe;
import emeraldjelly.mystica.init.ModItems;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class CauldronRecipe implements ICauldronRecipe { //What am  Missing in this class? Where do I make all of this code happen?

    private ItemStack resultItem = ItemStack.EMPTY;

    public CauldronRecipe(List<Item> items, ItemStack output) {
       this.resultItem = output;
    }

    @Override
    public boolean matches(List<ItemStack> itemStacks) {
        for (int i = 0; i < itemStacks.size(); i++) {
            ItemStack itemstack = itemStacks.get(i);
            if (itemstack != ItemStack.EMPTY) {
                boolean flag = false;

                for (ItemStack itemstack1 : itemStacks) {
                    if (!itemstack.hasTagCompound() && itemstack.getItem() == itemstack1.getItem() && (
                            itemstack1.getMetadata() == OreDictionary.WILDCARD_VALUE ||
                                    itemstack.getMetadata() == itemstack1.getMetadata())) {
                        flag = true;
                        itemStacks.remove(itemstack1);
                        break;
                    }
                }
                if (!flag) {
                    return false;
                }
            }
        }
        return itemStacks.isEmpty();
    }

    @Override
    public ItemStack getCraftingResult() {
        return resultItem;
    }
}

 

 

 

 

Now how do I call these methods when something is being created... Like how do I test the dropped items from my TileEntitySorcerersCauldron class?

Posted
3 hours ago, EmeraldJelly said:

public CauldronRecipe(List<Item> items, ItemStack output) {
  this.resultItem = output;
}

 

And how, pray tell, do you expect the list to be tracked?

 

12 hours ago, Draco18s said:
Quote


public boolean matches(List<ItemStack> itemStacks) {
    for (int i = 0; i < itemStacks.size(); i++) {
        for (ItemStack itemstack1 : itemStacks) {

 

Why are you matching a list against itself?

 

3 hours ago, EmeraldJelly said:

CauldronRecipes extends CauldronRecipe

Why is your "list of recipes" also a recipe?

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted (edited)

Sigh... Im asking you I: Clearly I am too stupid to understand what you are telling me sooo.... Either that or my brain just isn't working recently.

Edited by EmeraldJelly

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements




  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Version 1.19 - Forge 41.0.63 I want to create a wolf entity that I can ride, so far it seems to be working, but the problem is that when I get on the wolf, I can’t control it. I then discovered that the issue is that the server doesn’t detect that I’m riding the wolf, so I’m struggling with synchronization. However, it seems to not be working properly. As I understand it, the server receives the packet but doesn’t register it correctly. I’m a bit new to Java, and I’ll try to provide all the relevant code and prints *The comments and prints are translated by chatgpt since they were originally in Spanish* Thank you very much in advance No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. MountableWolfEntity package com.vals.valscraft.entity; import com.vals.valscraft.network.MountSyncPacket; import com.vals.valscraft.network.NetworkHandler; import net.minecraft.client.Minecraft; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.animal.Wolf; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.Entity; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.network.PacketDistributor; public class MountableWolfEntity extends Wolf { private boolean hasSaddle; private static final EntityDataAccessor<Byte> DATA_ID_FLAGS = SynchedEntityData.defineId(MountableWolfEntity.class, EntityDataSerializers.BYTE); public MountableWolfEntity(EntityType<? extends Wolf> type, Level level) { super(type, level); this.hasSaddle = false; } @Override protected void defineSynchedData() { super.defineSynchedData(); this.entityData.define(DATA_ID_FLAGS, (byte)0); } public static AttributeSupplier.Builder createAttributes() { return Wolf.createAttributes() .add(Attributes.MAX_HEALTH, 20.0) .add(Attributes.MOVEMENT_SPEED, 0.3); } @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemstack = player.getItemInHand(hand); if (itemstack.getItem() == Items.SADDLE && !this.hasSaddle()) { if (!player.isCreative()) { itemstack.shrink(1); } this.setSaddle(true); return InteractionResult.SUCCESS; } else if (!level.isClientSide && this.hasSaddle()) { player.startRiding(this); MountSyncPacket packet = new MountSyncPacket(true); // 'true' means the player is mounted NetworkHandler.CHANNEL.sendToServer(packet); // Ensure the server handles the packet return InteractionResult.SUCCESS; } return InteractionResult.PASS; } @Override public void travel(Vec3 travelVector) { if (this.isVehicle() && this.getControllingPassenger() instanceof Player) { System.out.println("The wolf has a passenger."); System.out.println("The passenger is a player."); Player player = (Player) this.getControllingPassenger(); // Ensure the player is the controller this.setYRot(player.getYRot()); this.yRotO = this.getYRot(); this.setXRot(player.getXRot() * 0.5F); this.setRot(this.getYRot(), this.getXRot()); this.yBodyRot = this.getYRot(); this.yHeadRot = this.yBodyRot; float forward = player.zza; float strafe = player.xxa; if (forward <= 0.0F) { forward *= 0.25F; } this.flyingSpeed = this.getSpeed() * 0.1F; this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED) * 1.5F); this.setDeltaMovement(new Vec3(strafe, travelVector.y, forward).scale(this.getSpeed())); this.calculateEntityAnimation(this, false); } else { // The wolf does not have a passenger or the passenger is not a player System.out.println("No player is mounted, or the passenger is not a player."); super.travel(travelVector); } } public boolean hasSaddle() { return this.hasSaddle; } public void setSaddle(boolean hasSaddle) { this.hasSaddle = hasSaddle; } @Override protected void dropEquipment() { super.dropEquipment(); if (this.hasSaddle()) { this.spawnAtLocation(Items.SADDLE); this.setSaddle(false); } } @SubscribeEvent public static void onServerTick(TickEvent.ServerTickEvent event) { if (event.phase == TickEvent.Phase.START) { MinecraftServer server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(); if (server != null) { for (ServerPlayer player : server.getPlayerList().getPlayers()) { if (player.isPassenger() && player.getVehicle() instanceof MountableWolfEntity) { MountableWolfEntity wolf = (MountableWolfEntity) player.getVehicle(); System.out.println("Tick: " + player.getName().getString() + " is correctly mounted on " + wolf); } } } } } private boolean lastMountedState = false; @Override public void tick() { super.tick(); if (!this.level.isClientSide) { // Only on the server boolean isMounted = this.isVehicle() && this.getControllingPassenger() instanceof Player; // Only print if the state changed if (isMounted != lastMountedState) { if (isMounted) { Player player = (Player) this.getControllingPassenger(); // Verify the passenger is a player System.out.println("Server: Player " + player.getName().getString() + " is now mounted."); } else { System.out.println("Server: The wolf no longer has a passenger."); } lastMountedState = isMounted; } } } @Override public void addPassenger(Entity passenger) { super.addPassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(true)); } } } @Override public void removePassenger(Entity passenger) { super.removePassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is no longer mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(false)); } } } @Override public boolean isControlledByLocalInstance() { Entity entity = this.getControllingPassenger(); return entity instanceof Player; } @Override public void positionRider(Entity passenger) { if (this.hasPassenger(passenger)) { double xOffset = Math.cos(Math.toRadians(this.getYRot() + 90)) * 0.4; double zOffset = Math.sin(Math.toRadians(this.getYRot() + 90)) * 0.4; passenger.setPos(this.getX() + xOffset, this.getY() + this.getPassengersRidingOffset() + passenger.getMyRidingOffset(), this.getZ() + zOffset); } } } MountSyncPacket package com.vals.valscraft.network; import com.vals.valscraft.entity.MountableWolfEntity; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class MountSyncPacket { private final boolean isMounted; public MountSyncPacket(boolean isMounted) { this.isMounted = isMounted; } public void encode(FriendlyByteBuf buffer) { buffer.writeBoolean(isMounted); } public static MountSyncPacket decode(FriendlyByteBuf buffer) { return new MountSyncPacket(buffer.readBoolean()); } public void handle(NetworkEvent.Context context) { context.enqueueWork(() -> { ServerPlayer player = context.getSender(); // Get the player from the context if (player != null) { // Verifies if the player has dismounted if (!isMounted) { Entity vehicle = player.getVehicle(); if (vehicle instanceof MountableWolfEntity wolf) { // Logic to remove the player as a passenger wolf.removePassenger(player); System.out.println("Server: Player " + player.getName().getString() + " is no longer mounted."); } } } }); context.setPacketHandled(true); // Marks the packet as handled } } networkHandler package com.vals.valscraft.network; import com.vals.valscraft.valscraft; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.network.NetworkRegistry; import net.minecraftforge.network.simple.SimpleChannel; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class NetworkHandler { private static final String PROTOCOL_VERSION = "1"; public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel( new ResourceLocation(valscraft.MODID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals ); public static void init() { int packetId = 0; // Register the mount synchronization packet CHANNEL.registerMessage( packetId++, MountSyncPacket.class, MountSyncPacket::encode, MountSyncPacket::decode, (msg, context) -> msg.handle(context.get()) // Get the context with context.get() ); } }  
    • Do you use features of inventory profiles next (ipnext) or is there a change without it?
    • Remove rubidium - you are already using embeddium, which is a fork of rubidium
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

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