#how to add custom attack sounds and sweep particle to a weapon

39 messages · Page 1 of 1 (latest)

median knot
#

im very new and just want a general idea of the steps i have to go through, do i have to make an override or is there already something i can do to change it?

calm folio
#

Did you ever figure it out?
Because I'm trying to do it as well and can't figure out how to do it

indigo walrus
#

same

cerulean kite
#

assuming latest mc version:
PlayerEnity#attack uses the SoundEvents.ENTITY_PLAYER_ATTACK_SWEEP sound and PlayerEntity#spawnSweepAttackParticles to spawn the sweep particles

Mixin to PlayerEntity
for the particles:
ModifyExpressionValue into PlayerEntity#spawnSweepAttackParticles
and at the FIELD targetting the ParticleTypes.SWEEP_ATTACK

for the sound:
ModifyExpressionValue into PlayerEntity#attack and at the FIELD targetting SoundEvents.ENTITY_PLAYER_ATTACK_SWEEP

calm folio
#

Will that change the default sweep particle or add a new one that can be used by a specific item?
Sorry, haven't really meddled with mixin yet

cerulean kite
#

ModifyExpressionValue provides you with the original thing you are modifying (in this case the particle type or the sweep sound event)

based on your own code, you either return the original (does not meet your condition for your own values), or you provide new values

#

lets say you want to modify the doThing method by changing the action provided to a method doAction. you can ModifyExpressionValue the getAction invoke, and the code ends up looking something like (overly simplified):

original:

public void doThing() {
  doAction( getAction() );
}

mixin modified

public void doThing() {
  // your annotation tells it to wrap the getAction call and change the result
  doAction( getModifiedAction(getAction()) );
}

// this is the method in your mixin. its added to the target class
private Action getModifiedAction(Action original) {
  if (!shouldChangeAction()) return original
  return MY_CUSTOM_ACTION;
}
calm folio
#

Would the mixin starts as :

public class PlayerEntityMixin extends PlayerEntity {

    @ModifyExpressionValue()
}

?

calm folio
#

(In this case it's for the sweep particles)

median knot
#

this actually helped a bit

#

im gonna reattempt this since i dropped the idea 😭

calm folio
#

I might ask for help again tomorrow, I didn't get further than that 😂

cerulean kite
#

you would have 2 annotations

for the first:

ModifyExpressionValue into PlayerEntity#spawnSweepAttackParticles
and at the FIELD targetting the ParticleTypes.SWEEP_ATTACK

spawnSweepAttackParticles is the method
in the at, FIELD is the value, SWEEP_ATTACK is the target

you should let the minecraft development plugin autocomplete those for you

calm folio
#

Ooooh it can do that ?

cerulean kite
#

(this assumes your thing is in the right tag or is a SwordItem)

calm folio
#

It is indeed a SwordItem

cerulean kite
#

for the second

ModifyExpressionValue into PlayerEntity#attack and at the FIELD targetting SoundEvents.ENTITY_PLAYER_ATTACK_SWEEP

attack is the method
in the at, FIELD is the value, ENTITY_PLAYER_ATTACK_SWEEP is the target

calm folio
#

And so I would need an if statement in the mixin to choose which sweep attack gets called?

#

Or is that done another way?

cerulean kite
#

yep

#

if (isMyCustomThing) return MY_CUSTOM_SOUND/PARTICLE;
return original;

calm folio
#

Alright, will try that tomorrow !
(And probably come back with more questions xD)
Thanks for your kind help !

indigo walrus
#

i tried something but it didnt work:

    private void injectSpawnSweepAttackParticles(CallbackInfo info) {
        PlayerEntity player = (PlayerEntity) (Object) this;
        if (player.getMainHandStack() == ModItems.AETHERIAL_BLADE.getDefaultStack()) {
            double d = (double) (-MathHelper.sin(player.getYaw() * 0.017453292F));
            double e = (double) MathHelper.cos(player.getYaw() * 0.017453292F);
            if (player.getWorld() instanceof ServerWorld) {
                    ((ServerWorld) player.getWorld()).spawnParticles(ParticleTypes.ANGRY_VILLAGER, player.getX() + d, player.getBodyY(0.5), player.getZ() + e, 0, d, 0.0, e, 0.0);
            }
        }
    }```
cerulean kite
#

ModifyExpressionValue not inject

#
@Mixin(PlayerEntity.class)
public abstract class PlayerEntityMixin extends LivingEntity {

    @ModifyExpressionValue(method="", at=@At(value="", target=""))
    private ReturnTypeHere myMethod(ReturnTypeHere original) {
      // My Checks Here and conditional return
      return original;
    }
}
#

(it will ask for a constructor but mixin will ignore the constructor, let the IDE make a default one, thats fine)

indigo walrus
#

i figured it out

#
    private void injectSpawnSweepAttackParticles(CallbackInfo info) {
        PlayerEntity player = (PlayerEntity) (Object) this;
        if (player.getMainHandStack().isOf(ModItems.AETHERIAL_BLADE)) {
            double d = (double) (-MathHelper.sin(player.getYaw() * 0.017453292F));
            double e = (double) MathHelper.cos(player.getYaw() * 0.017453292F);
            if (player.getWorld() instanceof ServerWorld) {
                    ((ServerWorld) player.getWorld()).spawnParticles(ParticleTypes.ANGRY_VILLAGER, player.getX() + d, player.getBodyY(0.5), player.getZ() + e, 0, d, 0.0, e, 0.0);
            }
            info.cancel();
        }
    }```
cerulean kite
#

just keep in mind that any other mod that spawns sweep particles without requiring a stack check could be broken by your mixin

#

(silently, it just wont work because you return from the method early)

calm folio
#

what would the return type be in this case?

calm folio
#
public abstract class PlayerEntityMixin extends LivingEntity {

    protected PlayerEntityMixin(EntityType<? extends LivingEntity> entityType, World world) {
        super(entityType, world);
    }

    @ModifyExpressionValue(method="spawnSweepAttackParticles", at=@At(value="FIELD", target="ENTITY_PLAYER_ATTACK_SWEEP "))
    private void spawnSweepAttackHoelyBeheader(void original) {
        PlayerEntity player = (PlayerEntity) (Object) this;
        if (player.getMainHandStack().isOf(ModItems.HOELY_BEHEADER)) {
            double d = (double) (-MathHelper.sin(this.getYaw() * ((float) Math.PI / 180F)));
            double e = (double) MathHelper.cos(this.getYaw() * ((float) Math.PI / 180F));
            if (this.getWorld() instanceof ServerWorld) {
                ((ServerWorld) this.getWorld()).spawnParticles(ModParticles.HOELY_BEHEADER_SWEEP_ATTACK_PARTICLE,
                        this.getX() + d, this.getBodyY((double) 0.5F), this.getZ() + e, 0, d, (double) 0.0F, e, (double) 0.0F);
            }
            return original;
        }
    }
}```
median knot
#

is hoely a pun

#

😭

calm folio
#

yes x)

#

The item is a scythe x)

median knot
#

thats fire

calm folio
#

thank you :)