Jump to content

Recommended Posts

Posted

I have a custom entity with model and custom AI task. I want make an attack animation for my model class, that will run when entity performs my custom AI task. I already tried some ways, but ALL my entities always animating, when fighting only one of them. Tell me, please, what is the most correct way to bind an animation to entity tasks.

  

Posted
  On 12/15/2018 at 8:50 PM, TheOrangeInd said:

but ALL my entities always animating, when fighting only one of them.

Expand  

This souns like you are either using static fields to store animation state or are accessing the model/renderer from your AI task directly neither of which is correct.

  On 12/15/2018 at 8:50 PM, TheOrangeInd said:

Tell me, please, what is the most correct way to bind an animation to entity tasks.

Expand  

Store and update a value of a field within your entity, sync it with the DataManager and use the value of that field to determine the animation.

Posted
  On 12/16/2018 at 3:44 AM, V0idWa1k3r said:

Store and update a value of a field within your entity, sync it with the DataManager

Expand  

In the last try I did it this way:

That is parts of

my entity class

	protected NBTTagCompound compound = new NBTTagCompound();

	@Override
    public void compoundInit()
    {
        compound.setByte("attackTime", (byte)0);
        compound.setBoolean("isAttacking", false);
    }

	public void setAttacking(Boolean attacking)
    {
        compound.setBoolean("isAttacking", attacking);
        if(attacking) setAttackTimer((byte)ATTACK_TIME);
        syncEntityOnClient();
    }

    public boolean isAttacking()
    {
        return compound.getBoolean("isAttacking");
    }

    public void setAttackTimer(byte value)
    {
        compound.setByte("attackTime", value);
        syncEntityOnClient();
    }

    public void decreaseAttackTimer()
    {
        compound.setByte("attackTime", (byte)(getAttackTimer() - 1));
        syncEntityOnClient();
    }

    public byte getAttackTimer()
    {
        return compound.getByte("attackTime");
    }

    @Override
    public void setCompound(NBTTagCompound setTo)
    {
        compound = setTo;
    }

    @Override
    public NBTTagCompound getCompound()
    {
        return compound;
    }

    @Override
    public void syncEntityOnClient()
    {
        Sync.sendEntitySyncToClient(this);
    }

 

my AI class

public boolean shouldExecute()
{
    EntityLivingBase target = this.entityHost.getAttackTarget();

    if (target == null)
    {
        return false;
    }
    else
    {
        if(this.entityHost.getDistanceSq(target) < this.maxAttackDistance && this.entityHost.getDistance(target) > 4 && target.getHealth() > 5)
        {
            this.attackTarget = target;
            this.entityHost.setAttacking(true);
            return true;
        }
        else
        {
            this.entityHost.setAttacking(false);
            return false;
        }
    }
}

public boolean shouldContinueExecuting()
{
    if (entityHost.getAttackTimer() > 0)
    {
        entityHost.decreaseAttackTimer();
    }
    return this.shouldExecute() || !this.entityHost.getNavigator().noPath();
}

 

my model class

	@Override
    public void setLivingAnimations(EntityLivingBase entitylivingbaseIn, float limbSwing, float limbSwingAmount, float partialTickTime)
    {
        float phase[] = {0.1F, 0.2F, 0.1F, -0.1F, -0.3F, -0.4F, -0.3F, -0.2F, -0.1F, 0.0F};

        boolean attacking = ((EntityThrower)entitylivingbaseIn).isAttacking();
        int time = ((EntityThrower)entitylivingbaseIn).getAttackTimer();

        if(attacking)
        {
            if(time > 0)
            {
                this.jawL.rotateAngleX = -0.81F + phase[time - 1];
                this.jawR.rotateAngleX = -0.81F + phase[time - 1];
            }
        }
    }

 

So, I tried using NBTTagCompound to save and load information about my entities, but it still doesn't work.

What am I doing wrong?

Posted
  On 12/16/2018 at 8:07 AM, TheOrangeInd said:

What am I doing wrong?

Expand  

Well first and foremost you are using NBTTagCompound for whatever god unknown reason. Don't use it, NBT is for (de)serializatio only.

 

  On 12/16/2018 at 8:07 AM, TheOrangeInd said:

public void setAttacking(Boolean attacking)

Expand  

Any particular reason you are using boxed values? You should not be doing that.

 

  On 12/16/2018 at 8:07 AM, TheOrangeInd said:

Sync.sendEntitySyncToClient(this);

Expand  

What does this do? You have a DataManager class for syncing entity related data. Use it. Don't reinvent the wheel.

 

  On 12/16/2018 at 8:07 AM, TheOrangeInd said:

if(attacking) { if(time > 0) { this.jawL.rotateAngleX = -0.81F + phase[time - 1]; this.jawR.rotateAngleX = -0.81F + phase[time - 1]; } }

Expand  

Since models are singletons you must either include an else with default rotations or reset the rotations. Otherwise the moment attacking is true for one entity the model changes for all of them. Which is your issue.

  • Thanks 1
Posted
  On 12/16/2018 at 8:21 AM, V0idWa1k3r said:

Well first and foremost you are using NBTTagCompound for whatever god unknown reason. Don't use it, NBT is for (de)serializatio only.

 

Any particular reason you are using boxed values? You should not be doing that.

 

What does this do? You have a DataManager class for syncing entity related data. Use it. Don't reinvent the wheel.

 

Since models are singletons you must either include an else with default rotations or reset the rotations. Otherwise the moment attacking is true for one entity the model changes for all of them. Which is your issue.

Expand  

I had no model animation experience before. Now, after following your recommendatios, I got a correctly working animation. Thank you very much! 

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

    • Managed to solve the issue myself. Solved by a fresh modpack instance.
    • Hello, so straight to the problem. Today i wanted to startup Enigmatica as usual and it just wont startup. Last night everything worked fine, i didnt even turn off my pc. Crash log: https://mclo.gs/GJ6Kcy1
    • Rubidium and Embeddium are versions of the same mod, you can only have one. I believe Embeddium is the one that's actively maintained.
    • Hello, New to modding, but have a solid CS foundation. I've created multiple custom BlockEntities that all have the same issue, which is that the inventory only updates on right click (overriding the useItemOn method). I've seen multiple posts on here outlining a similar issue to mine, but I've already implemented the solution of: overriding the correct methods in the BlockEntity class and calling setChanged(). I've tried every different place for setChanged() to no success. I'm wondering if I'm missing something else or if there was some change to sending data to the client in 1.21.5? Or will I have to use a custom packet sender? Here is the code for one of my BlockEntity classes with a single inventory slot: public class MyCustomBlockEntity extends BlockEntity { public final ItemStackHandler inventory = new ItemStackHandler(1) { @Override protected int getStackLimit(int slot, @NotNull ItemStack stack) { return 1; } @Override protected void onContentsChanged(int slot) { setChanged(); if (!level.isClientSide()) { level.setBlockAndUpdate(getBlockPos(), getBlockState()); } } }; public MyCustomBlockEntity(BlockPos pPos, BlockState pBlockState) { super(ModBlockEntities.MY_CUSTOM_BE.get(), pPos, pBlockState); } public void clearContents() { inventory.setStackInSlot(0, ItemStack.EMPTY); } public void dropItem() { SimpleContainer inv = new SimpleContainer(inventory.getSlots()); inv.setItem(0, inventory.getStackInSlot(0)); Containers.dropContents(this.level, this.worldPosition, inv); } @Override public void setRemoved() { dropItem(); super.setRemoved(); } @Override protected void saveAdditional(CompoundTag pTag, HolderLookup.Provider pRegistries) { super.saveAdditional(pTag, pRegistries); pTag.put("inventory", inventory.serializeNBT(pRegistries)); } @Override protected void loadAdditional(CompoundTag pTag, HolderLookup.Provider pRegistries) { super.loadAdditional(pTag, pRegistries); inventory.deserializeNBT(pRegistries, pTag.getCompound("inventory").get()); } @Override public Packet<ClientGamePacketListener> getUpdatePacket() { return ClientboundBlockEntityDataPacket.create(this); } @Override public CompoundTag getUpdateTag(HolderLookup.Provider pRegistries) { return saveWithoutMetadata(pRegistries); } } Mostly encountering the issue when calling the clearContents() method anywhere outside of useItemOn() in the Block class. I've also tried overriding both the handleUpdateTag() and onDataPacket() methods, calling their super along with loadAdditional(), but neither changed the outcome. Thanks in advance for any replies.
    • Hi all! I’m working on a Jurassic Park-themed mod for Minecraft 1.20.1, aiming to include dinosaurs, fossils, DNA extraction, and cool machines. This is a free project, mainly passion-driven, and I’ll give full credit to everyone involved. this is the perfect opportunity for beginners of modeling and coding. This project will give you experience and a creative freedom If you love dinosaurs and Minecraft modding, hit me up! Thanks! Add Me ogfrost. <--- Discord
  • Topics

×
×
  • Create New...

Important Information

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