mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-11 15:57:32 +00:00
Enhance LivingBreathEvent and LivingDrownEvent. Closes #9680
Also remove 3.5MB of useless data from the installer.
This commit is contained in:
1 parent
b680d09359
commit
f65381fbff
5 files changed
+188
-51
No files matched your search
Binary file not shown.
|
Before Width: | Height: | Size: 3.4 MiB |
@@ -53,11 +53,12 @@
|
||||
public boolean m_6040_() {
|
||||
return this.m_6336_() == MobType.f_21641_;
|
||||
}
|
||||
@@ -352,6 +_,8 @@
|
||||
@@ -352,6 +_,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ net.minecraftforge.common.ForgeHooks.onLivingBreathe(this, -m_7302_(0), m_7305_(0));
|
||||
+ int airSupply = this.m_20146_();
|
||||
+ net.minecraftforge.common.ForgeHooks.onLivingBreathe(this, airSupply - m_7302_(airSupply), m_7305_(airSupply) - airSupply);
|
||||
+ if (false) // Forge: Handled in ForgeHooks#onLivingBreathe(LivingEntity, int, int)
|
||||
if (this.m_204029_(FluidTags.f_13131_) && !this.m_9236_().m_8055_(BlockPos.m_274561_(this.m_20185_(), this.m_20188_(), this.m_20189_())).m_60713_(Blocks.f_50628_)) {
|
||||
boolean flag1 = !this.m_6040_() && !MobEffectUtil.m_19588_(this) && (!flag || !((Player)this).m_150110_().f_35934_);
|
||||
|
||||
@@ -1565,16 +1565,22 @@ public class ForgeHooks
|
||||
* @param entity The living entity which is currently updated
|
||||
* @param consumeAirAmount The amount of air to consume when the entity is unable to breathe
|
||||
* @param refillAirAmount The amount of air to refill when the entity is able to breathe
|
||||
* @implNote This method needs to closely replicate the logic found right after the call site in {@link LivingEntity#baseTick()} as it overrides it.
|
||||
*/
|
||||
public static void onLivingBreathe(LivingEntity entity, int consumeAirAmount, int refillAirAmount)
|
||||
{
|
||||
// Check things that vanilla considers to be air - these will cause the air supply to be increased.
|
||||
boolean isAir = entity.getEyeInFluidType().isAir() || entity.level().getBlockState(BlockPos.containing(entity.getX(), entity.getEyeY(), entity.getZ())).is(Blocks.BUBBLE_COLUMN);
|
||||
boolean canBreathe = isAir || !entity.canDrownInFluidType(entity.getEyeInFluidType()) || MobEffectUtil.hasWaterBreathing(entity) || (entity instanceof Player && ((Player) entity).getAbilities().invulnerable);
|
||||
LivingBreatheEvent breatheEvent = new LivingBreatheEvent(entity, canBreathe, consumeAirAmount, refillAirAmount);
|
||||
// The following effects cause the entity to not drown, but do not cause the air supply to be increased.
|
||||
boolean canBreathe = !entity.canDrownInFluidType(entity.getEyeInFluidType()) || MobEffectUtil.hasWaterBreathing(entity) || (entity instanceof Player && ((Player) entity).getAbilities().invulnerable);
|
||||
LivingBreatheEvent breatheEvent = new LivingBreatheEvent(entity, isAir || canBreathe, consumeAirAmount, refillAirAmount, isAir);
|
||||
MinecraftForge.EVENT_BUS.post(breatheEvent);
|
||||
if (breatheEvent.canBreathe())
|
||||
{
|
||||
entity.setAirSupply(Math.min(entity.getAirSupply() + breatheEvent.getRefillAirAmount(), entity.getMaxAirSupply()));
|
||||
if (breatheEvent.canRefillAir())
|
||||
{
|
||||
entity.setAirSupply(Math.min(entity.getAirSupply() + breatheEvent.getRefillAirAmount(), entity.getMaxAirSupply()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1583,13 +1589,13 @@ public class ForgeHooks
|
||||
|
||||
if (entity.getAirSupply() <= 0)
|
||||
{
|
||||
LivingDrownEvent drownEvent = new LivingDrownEvent(entity, entity.getAirSupply() <= -20);
|
||||
LivingDrownEvent drownEvent = new LivingDrownEvent(entity, entity.getAirSupply() <= -20, 2.0F, 8);
|
||||
if (!MinecraftForge.EVENT_BUS.post(drownEvent) && drownEvent.isDrowning())
|
||||
{
|
||||
entity.setAirSupply(0);
|
||||
Vec3 vec3 = entity.getDeltaMovement();
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
for (int i = 0; i < drownEvent.getBubbleCount(); ++i)
|
||||
{
|
||||
double d2 = entity.getRandom().nextDouble() - entity.getRandom().nextDouble();
|
||||
double d3 = entity.getRandom().nextDouble() - entity.getRandom().nextDouble();
|
||||
@@ -1597,11 +1603,11 @@ public class ForgeHooks
|
||||
entity.level().addParticle(ParticleTypes.BUBBLE, entity.getX() + d2, entity.getY() + d3, entity.getZ() + d4, vec3.x, vec3.y, vec3.z);
|
||||
}
|
||||
|
||||
entity.hurt(entity.damageSources().drown(), 2.0F);
|
||||
if (drownEvent.getDamageAmount() > 0) entity.hurt(entity.damageSources().drown(), drownEvent.getDamageAmount());
|
||||
}
|
||||
}
|
||||
|
||||
if (isAir && !entity.level().isClientSide && entity.isPassenger() && entity.getVehicle() != null && !entity.getVehicle().canBeRiddenUnderFluidType(entity.getEyeInFluidType(), entity))
|
||||
if (!isAir && !entity.level().isClientSide && entity.isPassenger() && entity.getVehicle() != null && !entity.getVehicle().canBeRiddenUnderFluidType(entity.getEyeInFluidType(), entity))
|
||||
{
|
||||
entity.stopRiding();
|
||||
}
|
||||
|
||||
@@ -5,64 +5,109 @@
|
||||
|
||||
package net.minecraftforge.event.entity.living;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.eventbus.api.Cancelable;
|
||||
|
||||
/**
|
||||
* LivingBreatheEvent is fired whenever a living entity ticks.<br>
|
||||
* <br>
|
||||
* This event is fired via the {@link ForgeHooks#onLivingBreathe(LivingEntity, int, int)}.<br>
|
||||
* <br>
|
||||
* {@link #canBreathe()} contains if this entity can breathe.<br>
|
||||
* {@link #getConsumeAirAmount()} contains the amount of air that will be consumed if this entity can't breathe.<br>
|
||||
* {@link #getRefillAirAmount()} contains the amount of air that will be refilled if this entity can breathe.<br>
|
||||
* This event is fired via {@link ForgeHooks#onLivingBreathe(LivingEntity, int, int)}.<br>
|
||||
* <br>
|
||||
* This event is not {@link Cancelable}.<br>
|
||||
* <br>
|
||||
* This event does not have a result. {@link HasResult}
|
||||
**/
|
||||
public class LivingBreatheEvent extends LivingEvent
|
||||
{
|
||||
* <br>
|
||||
* This event is fired on {@link MinecraftForge#EVENT_BUS}
|
||||
*/
|
||||
public class LivingBreatheEvent extends LivingEvent {
|
||||
private boolean canBreathe;
|
||||
private boolean canRefillAir;
|
||||
private int consumeAirAmount;
|
||||
private int refillAirAmount;
|
||||
|
||||
public LivingBreatheEvent(LivingEntity entity, boolean canBreathe, int consumeAirAmount, int refillAirAmount)
|
||||
{
|
||||
@ApiStatus.Internal
|
||||
@Deprecated(forRemoval = true, since = "1.20.1")
|
||||
public LivingBreatheEvent(LivingEntity entity, boolean canBreathe, int consumeAirAmount, int refillAirAmount) {
|
||||
this(entity, canBreathe, consumeAirAmount, refillAirAmount, canBreathe);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public LivingBreatheEvent(LivingEntity entity, boolean canBreathe, int consumeAirAmount, int refillAirAmount, boolean canRefillAir) {
|
||||
super(entity);
|
||||
this.canBreathe = canBreathe;
|
||||
this.canRefillAir = canRefillAir;
|
||||
this.consumeAirAmount = Math.max(consumeAirAmount, 0);
|
||||
this.refillAirAmount = Math.max(refillAirAmount, 0);
|
||||
}
|
||||
|
||||
public boolean canBreathe()
|
||||
{
|
||||
/**
|
||||
* If the entity can breathe and {@link #canRefillAir()} returns true, their air value will be increased by {@link #getRefillAirAmount()}.<br>
|
||||
* If the entity can breathe and {@link #canRefillAir()} returns false, their air value will stay the same.<br>
|
||||
* If the entity cannot breathe, their air value will be reduced by {@link #getConsumeAirAmount()}.
|
||||
* @return True if the entity can breathe
|
||||
*/
|
||||
public boolean canBreathe() {
|
||||
return canBreathe;
|
||||
}
|
||||
|
||||
public void setCanBreathe(boolean canBreathe)
|
||||
{
|
||||
/**
|
||||
* Sets if the entity can breathe or not.
|
||||
* @param canBreathe The new value.
|
||||
*/
|
||||
public void setCanBreathe(boolean canBreathe) {
|
||||
this.canBreathe = canBreathe;
|
||||
}
|
||||
|
||||
public int getConsumeAirAmount()
|
||||
{
|
||||
/**
|
||||
* If the entity can breathe, {@link #canRefillAir()} will be checked to see if their air value should be refilled.
|
||||
* @return True if the entity can refill its air value
|
||||
*/
|
||||
public boolean canRefillAir() {
|
||||
return canRefillAir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the entity can refill its air value or not.
|
||||
* @param canRefillAir The new value.
|
||||
*/
|
||||
public void setCanRefillAir(boolean canRefillAir) {
|
||||
this.canRefillAir = canRefillAir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The amount the entity's {@linkplain LivingEntity#getAirSupply() air supply} will be reduced by if the entity {@linkplain #canBreathe() cannot breathe}.
|
||||
*/
|
||||
public int getConsumeAirAmount() {
|
||||
return consumeAirAmount;
|
||||
}
|
||||
|
||||
public void setConsumeAirAmount(int consumeAirAmount)
|
||||
{
|
||||
/**
|
||||
* Sets the new consumed air amount.
|
||||
* @param consumeAirAmount The new value.
|
||||
* @see #getConsumeAirAmount()
|
||||
*/
|
||||
public void setConsumeAirAmount(int consumeAirAmount) {
|
||||
this.consumeAirAmount = Math.max(consumeAirAmount, 0);
|
||||
}
|
||||
|
||||
public int getRefillAirAmount()
|
||||
{
|
||||
/**
|
||||
* @return The amount the entity's {@linkplain LivingEntity#getAirSupply() air supply} will be increased by if the entity {@linkplain #canBreathe() can breathe}.
|
||||
*/
|
||||
public int getRefillAirAmount() {
|
||||
return refillAirAmount;
|
||||
}
|
||||
|
||||
public void setRefillAirAmount(int refillAirAmount)
|
||||
{
|
||||
/**
|
||||
* Sets the new refilled air amount.
|
||||
*
|
||||
* @param refillAirAmount The new value.
|
||||
* @see #getRefillAirAmount()
|
||||
*/
|
||||
public void setRefillAirAmount(int refillAirAmount) {
|
||||
this.refillAirAmount = Math.max(refillAirAmount, 0);
|
||||
}
|
||||
}
|
||||
@@ -5,42 +5,127 @@
|
||||
|
||||
package net.minecraftforge.event.entity.living;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.world.damagesource.DamageSources;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.eventbus.api.Cancelable;
|
||||
|
||||
/**
|
||||
* LivingDrownEvent is fired whenever a living entity can't breathe and its air aupply is less than or equal to
|
||||
* zero.<br>
|
||||
* <br>
|
||||
* This event is fired via the {@link ForgeHooks#onLivingBreathe(LivingEntity, int, int)}.<br>
|
||||
* <br>
|
||||
* {@link #isDrowning()} contains if this entity is drowning.<br>
|
||||
* <br>
|
||||
* This event is {@link Cancelable}.<br>
|
||||
* If this event is canceled, this entity won't take drowning damage, no particles will be spawned and the air supply
|
||||
* won't be reset to zero ignoring if {@link #isDrowning()} is true or not.<br>
|
||||
* <br>
|
||||
* This event does not have a result. {@link HasResult}
|
||||
* LivingDrownEvent is fired whenever a living entity can't breathe and its air supply is less than or equal to zero.
|
||||
* <p>
|
||||
* This event is fired via {@link ForgeHooks#onLivingBreathe(LivingEntity, int, int)}.
|
||||
* <p>
|
||||
* This event is {@link Cancelable}. Effects of cancellation are noted in {@link #setCanceled(boolean)}.
|
||||
* <p>
|
||||
* This event does not {@linkplain HasResult have a result}.
|
||||
* This event is fired on {@link MinecraftForge#EVENT_BUS}
|
||||
**/
|
||||
@Cancelable
|
||||
public class LivingDrownEvent extends LivingEvent
|
||||
{
|
||||
public class LivingDrownEvent extends LivingEvent {
|
||||
private boolean isDrowning;
|
||||
private float damageAmount;
|
||||
private int bubbleCount;
|
||||
|
||||
public LivingDrownEvent(LivingEntity entity, boolean isDrowning)
|
||||
{
|
||||
/**
|
||||
* Constructs a new LivingDrownEvent.
|
||||
*
|
||||
* @param entity The entity that is drowning.
|
||||
* @param isDrowning If the entity is "actively" drowning, and would take damage.
|
||||
* @param damageAmount The amount of {@linkplain DamageSources#drown() drowning damage} the entity would take.
|
||||
* @param bubbleCount The number of {@linkplain ParticleTypes#BUBBLE} particles that will be spawned when actively drowning.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public LivingDrownEvent(LivingEntity entity, boolean isDrowning, float damageAmount, int bubbleCount) {
|
||||
super(entity);
|
||||
this.isDrowning = isDrowning;
|
||||
this.damageAmount = damageAmount;
|
||||
this.bubbleCount = bubbleCount;
|
||||
}
|
||||
|
||||
public boolean isDrowning()
|
||||
{
|
||||
|
||||
@ApiStatus.Internal
|
||||
@Deprecated(forRemoval = true, since = "1.20.1")
|
||||
public LivingDrownEvent(LivingEntity entity, boolean isDrowning) {
|
||||
this(entity, isDrowning, 2.0F, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns true if the entity is "actively" drowning.<br>
|
||||
* For most entities, this happens when their air supply reaches -20.<br>
|
||||
* When this is true, the entity will take damage, spawn particles, and reset their air supply to 0.
|
||||
*
|
||||
* @return If the entity is actively drowning.
|
||||
*/
|
||||
public boolean isDrowning() {
|
||||
return isDrowning;
|
||||
}
|
||||
|
||||
public void setDrowning(boolean isDrowning)
|
||||
{
|
||||
/**
|
||||
* Sets if the entity is actively drowning.
|
||||
*
|
||||
* @param isDrowning The new value.
|
||||
* @see #isDrowning()
|
||||
*/
|
||||
public void setDrowning(boolean isDrowning) {
|
||||
this.isDrowning = isDrowning;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of {@linkplain DamageSources#drown() drowning damage} the entity would take.<br>
|
||||
* Drowning damage is only inflicted if the entity is {@linkplain #isDrowning() actively drowning}.<br>
|
||||
* For vanilla entities, the default amount of damage is 2 (1 heart).
|
||||
* <p>
|
||||
* If the damage amount is less than or equal to zero, {@link Entity#hurt} will not be called.
|
||||
*
|
||||
* @return The amount of damage that will be dealt to the entity when actively drowning.
|
||||
*/
|
||||
public float getDamageAmount() {
|
||||
return damageAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount of drowning damage that may be inflicted.
|
||||
*
|
||||
* @param damageAmount The new value.
|
||||
* @see #getDamageAmount()
|
||||
*/
|
||||
public void setDamageAmount(float damageAmount) {
|
||||
this.damageAmount = damageAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of {@linkplain ParticleTypes#BUBBLE} particles that would be spawned.<br>
|
||||
* Bubbles are only spawned if the entity is {@linkplain #isDrowning() actively drowning}.<br>
|
||||
* For vanilla entities, the default value is 8 particles.
|
||||
*
|
||||
* @return The number of bubble particles that will spawn when actively drowning.
|
||||
*/
|
||||
public int getBubbleCount() {
|
||||
return bubbleCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount of bubbles that may be spawned.
|
||||
*
|
||||
* @param bubbleCount The new value.
|
||||
* @see #getBubbleCount()
|
||||
*/
|
||||
public void setBubbleCount(int bubbleCount) {
|
||||
this.bubbleCount = bubbleCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the drowning event.<br>
|
||||
* Cancellation is mostly equivalent to {@link #setDrowning(boolean)} with a value of false.<br>
|
||||
* However, this also incurs the usual side effects of cancellation.
|
||||
*/
|
||||
@Override
|
||||
public void setCanceled(boolean cancel) {
|
||||
super.setCanceled(cancel);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user