package eu.abdelbaki.cmmodular; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import net.minecraft.core.Holder; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.ai.attributes.Attribute; import net.minecraft.world.entity.ai.attributes.AttributeInstance; import net.minecraft.world.entity.ai.attributes.AttributeMap; import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.neoforged.bus.api.IEventBus; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.event.entity.player.PlayerEvent; /** * Keeps an attribute that a piece of equipment grants from quietly going * missing. * *
Modifiers off worn and held items are transient: vanilla reads them when * the equipment changes and puts them in the entity's attribute map, and that * map is the only place they live. Change dimension and they can be gone - the * player is rebuilt on the way through, no equipment change follows, and so * nothing puts them back until the piece is taken off and put on again. Cinder * essence's fire immunity is the one that gets noticed, because the Nether is * exactly where it was wanted. * *
Two answers, because a modifier can be missing in two places. The map is
* rebuilt from the equipment after a dimension change or a respawn, which is
* what re-equipping would have done and which fixes every attribute rather than
* only this mod's. And when one of this mod's own attributes is read, the
* equipment is consulted as a fallback - the same data vanilla applies from, so
* the answer is the same whether or not the map ever lost it.
*/
public final class EquipmentAttributes {
private EquipmentAttributes() {
}
static void register(IEventBus modBus) {
NeoForge.EVENT_BUS.addListener(EquipmentAttributes::onChangedDimension);
NeoForge.EVENT_BUS.addListener(EquipmentAttributes::onRespawn);
}
private static void onChangedDimension(PlayerEvent.PlayerChangedDimensionEvent event) {
reapply(event.getEntity());
}
private static void onRespawn(PlayerEvent.PlayerRespawnEvent event) {
reapply(event.getEntity());
}
/** Puts every modifier the worn and held items grant back into the map. */
private static void reapply(Player player) {
AttributeMap attributes = player.getAttributes();
for (EquipmentSlot slot : EquipmentSlot.values()) {
ItemStack stack = player.getItemBySlot(slot);
if (stack.isEmpty()) {
continue;
}
Multimap Only additive modifiers are counted, which is all this mod grants.
*/
static double value(LivingEntity entity, Holder