mirror of
https://github.com/Pridecraft-Studios/joy.git
synced 2025-08-03 06:26:00 -04:00
parent
47316b94c6
commit
c2269dc07d
@ -2,71 +2,48 @@ package gay.pridecraft.joy.mixin.client;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import gay.pridecraft.joy.registry.JoyItems;
|
||||
import gay.pridecraft.joy.registry.JoyParticles;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import gay.pridecraft.joy.misc.ParticleEmitter;
|
||||
import gay.pridecraft.joy.tags.JoyItemTags;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.packet.s2c.play.EntityStatusS2CPacket;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.particle.ParticleEffect;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
@Mixin(ClientPlayNetworkHandler.class)
|
||||
public abstract class ClientPlayNetworkHandlerMixin {
|
||||
@Shadow
|
||||
public abstract ClientWorld getWorld();
|
||||
|
||||
@WrapOperation(method = "getActiveTotemOfUndying", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z"))
|
||||
private static boolean modifyTotemOfUndyingAnimation(ItemStack instance, Item item, Operation<Boolean> original) {
|
||||
return instance.isOf(JoyItems.TOTEM_OF_PRIDE) || original.call(instance, item);
|
||||
return instance.isIn(JoyItemTags.TOTEM_OF_UNDYING) || original.call(instance, item);
|
||||
}
|
||||
|
||||
@Inject(at = @At("HEAD"), method = "onEntityStatus")
|
||||
private void onCustomEntityStatus(EntityStatusS2CPacket packet, CallbackInfo ci) {
|
||||
if (this.getWorld() == null || packet.getStatus() != 36) {
|
||||
return;
|
||||
@ModifyArg(method = "onEntityStatus",
|
||||
at = @At(value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/particle/ParticleManager;addEmitter(Lnet/minecraft/entity/Entity;Lnet/minecraft/particle/ParticleEffect;I)V"))
|
||||
private ParticleEffect changeTotemParticle(Entity entity, ParticleEffect original, int maxAge) {
|
||||
if (entity instanceof LivingEntity living &&
|
||||
getActiveTotemOfUndying(living).getItem() instanceof ParticleEmitter emitter) {
|
||||
return emitter.joy$getEffect();
|
||||
}
|
||||
|
||||
final var client = MinecraftClient.getInstance();
|
||||
|
||||
//noinspection ResultOfMethodCallIgnored - unnecessary
|
||||
client.submit(() -> {
|
||||
final World world = this.getWorld();
|
||||
final Entity entity = packet.getEntity(world);
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
client.particleManager.addEmitter(entity, JoyParticles.TOTEM_OF_PRIDE_PARTICLE, 30);
|
||||
|
||||
world.playSound(entity.getX(), entity.getY(), entity.getZ(), SoundEvents.ITEM_TOTEM_USE, entity.getSoundCategory(), 1.f, 1.f, false);
|
||||
|
||||
if (entity == client.player) {
|
||||
client.gameRenderer.showFloatingItem(modifyTotem(client.player));
|
||||
}
|
||||
});
|
||||
return original;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static ItemStack modifyTotem(PlayerEntity player) {
|
||||
private static ItemStack getActiveTotemOfUndying(LivingEntity player) {
|
||||
for (Hand hand : Hand.values()) {
|
||||
ItemStack itemStack = player.getStackInHand(hand);
|
||||
if (itemStack.isOf(JoyItems.TOTEM_OF_PRIDE)) {
|
||||
if (itemStack.isIn(JoyItemTags.TOTEM_OF_UNDYING)) {
|
||||
return itemStack;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
|
@ -27,5 +27,9 @@ public class JoyItemTagProvider extends FabricTagProvider.ItemTagProvider {
|
||||
getOrCreateTagBuilder(JoyItemTags.GLIDERS).addTag(
|
||||
JoyItemTags.ELYTRA
|
||||
);
|
||||
getOrCreateTagBuilder(JoyItemTags.TOTEM_OF_UNDYING).add(
|
||||
Items.TOTEM_OF_UNDYING,
|
||||
JoyItems.TOTEM_OF_PRIDE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
package gay.pridecraft.joy.item;
|
||||
|
||||
import gay.pridecraft.joy.misc.ParticleEmitter;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.particle.ParticleEffect;
|
||||
|
||||
/**
|
||||
* @author Ampflower
|
||||
* @since 1.0.0
|
||||
**/
|
||||
public class ParticleEmittingItem extends Item implements ParticleEmitter {
|
||||
private final ParticleEffect effect;
|
||||
|
||||
public ParticleEmittingItem(final Settings settings, final ParticleEffect effect) {
|
||||
super(settings);
|
||||
this.effect = effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParticleEffect joy$getEffect() {
|
||||
return effect;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package gay.pridecraft.joy.misc;
|
||||
|
||||
import net.minecraft.particle.ParticleEffect;
|
||||
|
||||
/**
|
||||
* @author Ampflower
|
||||
* @since 1.0.0
|
||||
**/
|
||||
public interface ParticleEmitter {
|
||||
ParticleEffect joy$getEffect();
|
||||
}
|
@ -1,56 +1,43 @@
|
||||
package gay.pridecraft.joy.mixin;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import gay.pridecraft.joy.registry.JoyItems;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import gay.pridecraft.joy.tags.JoyItemTags;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||
import net.minecraft.entity.effect.StatusEffects;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
@Mixin(LivingEntity.class)
|
||||
public abstract class LivingEntityMixin extends Entity {
|
||||
@Shadow public abstract ItemStack getStackInHand(Hand hand);
|
||||
|
||||
@Shadow public abstract void setHealth(float health);
|
||||
|
||||
@Shadow public abstract boolean clearStatusEffects();
|
||||
|
||||
@Shadow public abstract boolean addStatusEffect(StatusEffectInstance effect);
|
||||
|
||||
public LivingEntityMixin(EntityType<?> type, World world) {
|
||||
super(type, world);
|
||||
}
|
||||
|
||||
@WrapMethod(method = "tryUseTotem")
|
||||
public boolean useCustomTotem(DamageSource source, Operation<Boolean> original) {
|
||||
LivingEntityMixin entity = this;
|
||||
|
||||
ItemStack offhandStack = entity.getStackInHand(Hand.OFF_HAND);
|
||||
ItemStack mainHandStack = entity.getStackInHand(Hand.MAIN_HAND);
|
||||
|
||||
if (!offhandStack.isOf(JoyItems.TOTEM_OF_PRIDE) && !mainHandStack.isOf(JoyItems.TOTEM_OF_PRIDE)) return original.call(source);
|
||||
|
||||
if (offhandStack.isOf(JoyItems.TOTEM_OF_PRIDE)) offhandStack.decrement(1);
|
||||
else if (mainHandStack.isOf(JoyItems.TOTEM_OF_PRIDE)) mainHandStack.decrement(1);
|
||||
|
||||
|
||||
this.setHealth(1.0F);
|
||||
this.clearStatusEffects();
|
||||
|
||||
this.addStatusEffect(new StatusEffectInstance(StatusEffects.REGENERATION, 45 * 20, 1));
|
||||
this.addStatusEffect(new StatusEffectInstance(StatusEffects.FIRE_RESISTANCE, 40 * 20, 0));
|
||||
this.addStatusEffect(new StatusEffectInstance(StatusEffects.ABSORPTION, 5 * 20, 1));
|
||||
|
||||
this.getWorld().sendEntityStatus(entity, (byte) 36);
|
||||
|
||||
@WrapOperation(method = "tryUseTotem",
|
||||
at = @At(value = "INVOKE",
|
||||
target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z"))
|
||||
private boolean onCheckTotem(ItemStack self, Item other, Operation<Boolean> operation) {
|
||||
if (self.isIn(JoyItemTags.TOTEM_OF_UNDYING)) {
|
||||
return true;
|
||||
}
|
||||
return operation.call(self, other);
|
||||
}
|
||||
|
||||
@ModifyArg(method = "tryUseTotem",
|
||||
at = @At(value = "INVOKE",
|
||||
target = "Lnet/minecraft/stat/StatType;getOrCreateStat(Ljava/lang/Object;)Lnet/minecraft/stat/Stat;"))
|
||||
private Object modifyStatArgument(Object original, @Local ItemStack real) {
|
||||
if (real != null && !real.isEmpty()) {
|
||||
return real.getItem();
|
||||
}
|
||||
return original;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ package gay.pridecraft.joy.registry;
|
||||
import gay.pridecraft.joy.JoyUtil;
|
||||
import gay.pridecraft.joy.Pivot;
|
||||
import gay.pridecraft.joy.item.CustomElytraItem;
|
||||
import gay.pridecraft.joy.item.ParticleEmittingItem;
|
||||
import net.minecraft.component.DataComponentTypes;
|
||||
import net.minecraft.component.type.BundleContentsComponent;
|
||||
import net.minecraft.item.BrushItem;
|
||||
@ -24,7 +25,7 @@ public final class JoyItems {
|
||||
|
||||
public static final Item TOTEM_OF_PRIDE = registerItem(
|
||||
"totem_of_pride",
|
||||
new Item(new Item.Settings().maxCount(1))
|
||||
new ParticleEmittingItem(new Item.Settings().maxCount(1), JoyParticles.TOTEM_OF_PRIDE_PARTICLE)
|
||||
);
|
||||
|
||||
public static final Item PRIDE_BRUSH = registerItem(
|
||||
|
@ -13,7 +13,8 @@ import net.minecraft.util.Identifier;
|
||||
public final class JoyItemTags {
|
||||
public static final TagKey<Item>
|
||||
GLIDERS = common("gliders"),
|
||||
ELYTRA = common("elytra");
|
||||
ELYTRA = common("elytra"),
|
||||
TOTEM_OF_UNDYING = common("totem_of_undying");
|
||||
|
||||
private static TagKey<Item> joy(String name) {
|
||||
return TagKey.of(RegistryKeys.ITEM, JoyUtil.id(name));
|
||||
|
Loading…
x
Reference in New Issue
Block a user