'How do I make a Totem of Undying like item with Fabric?
Solution 1:[1]
The totem of undying is just a regular item, which is why there is no custom item class for it. Its special abilities come from how entities respond to having the item when they take damage.
As of minecraft 1.18.1, the totem of undying item is handled by the Living Entity class. This class contains the function damage which handles an entity takes damage.
if (this.isDead()) {
if (!this.tryUseTotem(source)) {
SoundEvent soundEvent = this.getDeathSound();
if (bl2 && soundEvent != null) {
this.playSound(soundEvent, this.getSoundVolume(), this.getSoundPitch());
}
this.onDeath(source);
}
}
If the entity is dead, it runs the function tryUseTotem. This is where the status effects for the totem of undying are applied.
private boolean tryUseTotem(DamageSource source) {
if (source.isOutOfWorld()) {
return false;
}
ItemStack itemStack = null;
for (Hand hand : Hand.values()) {
ItemStack itemStack2 = this.getStackInHand(hand);
if (!itemStack2.isOf(Items.TOTEM_OF_UNDYING)) continue;
itemStack = itemStack2.copy();
itemStack2.decrement(1);
break;
}
if (itemStack != null) {
if (this instanceof ServerPlayerEntity) {
ServerPlayerEntity serverPlayerEntity = (ServerPlayerEntity)this;
serverPlayerEntity.incrementStat(Stats.USED.getOrCreateStat(Items.TOTEM_OF_UNDYING));
Criteria.USED_TOTEM.trigger(serverPlayerEntity, itemStack);
}
this.setHealth(1.0f);
this.clearStatusEffects();
this.addStatusEffect(new StatusEffectInstance(StatusEffects.REGENERATION, 900, 1));
this.addStatusEffect(new StatusEffectInstance(StatusEffects.ABSORPTION, 100, 1));
this.addStatusEffect(new StatusEffectInstance(StatusEffects.FIRE_RESISTANCE, 800, 0));
this.world.sendEntityStatus(this, (byte)35);
}
return itemStack != null;
}
Finally, the sendEntityStatus function is called. This is handled by a variety of classes by functions called handleStatus or onEntityStatus. In particular, sending the byte 35 is handled by the ClientPlayNetworkHandler class.
@Override
public void onEntityStatus(EntityStatusS2CPacket packet) {
NetworkThreadUtils.forceMainThread(packet, this, this.client);
Entity entity = packet.getEntity(this.world);
if (entity != null) {
if (packet.getStatus() == 21) {
this.client.getSoundManager().play(new GuardianAttackSoundInstance((GuardianEntity)entity));
} else if (packet.getStatus() == 35) {
int i = 40;
this.client.particleManager.addEmitter(entity, ParticleTypes.TOTEM_OF_UNDYING, 30);
this.world.playSound(entity.getX(), entity.getY(), entity.getZ(), SoundEvents.ITEM_TOTEM_USE, entity.getSoundCategory(), 1.0f, 1.0f, false);
if (entity == this.client.player) {
this.client.gameRenderer.showFloatingItem(ClientPlayNetworkHandler.getActiveTotemOfUndying(this.client.player));
}
} else {
entity.handleStatus(packet.getStatus());
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Ross The Boss |