68 lines
3.0 KiB
Java
68 lines
3.0 KiB
Java
package eu.abdelbaki.cmmodular;
|
|
|
|
import net.minecraft.core.registries.Registries;
|
|
import net.minecraft.tags.FluidTags;
|
|
import net.minecraft.world.entity.ai.attributes.Attribute;
|
|
import net.minecraft.world.entity.ai.attributes.RangedAttribute;
|
|
import net.neoforged.bus.api.EventPriority;
|
|
import net.neoforged.bus.api.IEventBus;
|
|
import net.neoforged.neoforge.common.NeoForge;
|
|
import net.neoforged.neoforge.event.entity.EntityAttributeModificationEvent;
|
|
import net.neoforged.neoforge.event.entity.living.LivingBreatheEvent;
|
|
import net.neoforged.neoforge.registries.DeferredHolder;
|
|
import net.neoforged.neoforge.registries.DeferredRegister;
|
|
|
|
/**
|
|
* Sea serpent fang armour lets its wearer breathe underwater, which is what Ice
|
|
* and Fire's own Tide Guardian armour does and the only reason to hunt the
|
|
* thing.
|
|
*
|
|
* <p>There is no attribute for it and MIAPI has no property for it either - the
|
|
* closest data can get is a fake Respiration enchantment, which only postpones
|
|
* drowning. So this follows the pattern {@link FireImmunity} and
|
|
* {@link VacuumSeal} already set: an attribute of this mod's own that the
|
|
* material grants like any other, and a listener here that watches for it.
|
|
*
|
|
* <p>Half a lung per module, as with {@link VacuumSeal}: the fang grants 0.5 in
|
|
* each armour slot and nothing in hand, so it takes two worn pieces of it -
|
|
* two sockets, two pieces built of it, or a socketed piece that is both - to
|
|
* breathe, and a fang weapon breathes not at all. What a fang is worth in hand
|
|
* is {@link WaterCombat}'s.
|
|
*
|
|
* <p>It answers the same event {@link VacuumSeal} does but only underwater, so
|
|
* a fang is a fang and not half a spacesuit.
|
|
*/
|
|
public final class WaterBreathing {
|
|
private static final DeferredRegister<Attribute> ATTRIBUTES =
|
|
DeferredRegister.create(Registries.ATTRIBUTE, CMModular.MOD_ID);
|
|
|
|
/** At or above 1 the bearer never drowns; each worn fang module is 0.5. */
|
|
public static final DeferredHolder<Attribute, Attribute> WATER_BREATHING =
|
|
ATTRIBUTES.register("water_breathing", id -> new RangedAttribute(
|
|
"attribute.cmmodular.water_breathing", 0.0D, 0.0D, 1.0D).setSyncable(true));
|
|
|
|
private WaterBreathing() {
|
|
}
|
|
|
|
static void register(IEventBus modBus) {
|
|
ATTRIBUTES.register(modBus);
|
|
modBus.addListener(WaterBreathing::attachToEntities);
|
|
// Last, so it answers after whatever said there was no air.
|
|
NeoForge.EVENT_BUS.addListener(EventPriority.LOWEST, WaterBreathing::onBreathe);
|
|
}
|
|
|
|
/** Attributes only exist on an entity if they were added to its type. */
|
|
private static void attachToEntities(EntityAttributeModificationEvent event) {
|
|
event.getTypes().forEach(type -> event.add(type, WATER_BREATHING));
|
|
}
|
|
|
|
private static void onBreathe(LivingBreatheEvent event) {
|
|
if (event.canBreathe() || !event.getEntity().isEyeInFluid(FluidTags.WATER)) {
|
|
return;
|
|
}
|
|
if (EquipmentAttributes.value(event.getEntity(), WATER_BREATHING) >= 1.0D) {
|
|
event.setCanBreathe(true);
|
|
}
|
|
}
|
|
}
|