minecraft-src/net/minecraft/world/entity/projectile/Arrow.java
2025-07-04 03:45:38 +03:00

139 lines
4.6 KiB
Java

package net.minecraft.world.entity.projectile;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.particles.ColorParticleOption;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.network.syncher.SynchedEntityData.Builder;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.PotionContents;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;
public class Arrow extends AbstractArrow {
private static final int EXPOSED_POTION_DECAY_TIME = 600;
private static final int NO_EFFECT_COLOR = -1;
private static final EntityDataAccessor<Integer> ID_EFFECT_COLOR = SynchedEntityData.defineId(Arrow.class, EntityDataSerializers.INT);
private static final byte EVENT_POTION_PUFF = 0;
public Arrow(EntityType<? extends Arrow> entityType, Level level) {
super(entityType, level);
}
public Arrow(Level level, double x, double y, double z, ItemStack pickupItemStack, @Nullable ItemStack firedFromWeapon) {
super(EntityType.ARROW, x, y, z, level, pickupItemStack, firedFromWeapon);
this.updateColor();
}
public Arrow(Level level, LivingEntity owner, ItemStack pickupItemStack, @Nullable ItemStack firedFromWeapon) {
super(EntityType.ARROW, owner, level, pickupItemStack, firedFromWeapon);
this.updateColor();
}
private PotionContents getPotionContents() {
return this.getPickupItemStackOrigin().getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
}
private float getPotionDurationScale() {
return this.getPickupItemStackOrigin().getOrDefault(DataComponents.POTION_DURATION_SCALE, 1.0F);
}
private void setPotionContents(PotionContents potionContents) {
this.getPickupItemStackOrigin().set(DataComponents.POTION_CONTENTS, potionContents);
this.updateColor();
}
@Override
protected void setPickupItemStack(ItemStack pickupItemStack) {
super.setPickupItemStack(pickupItemStack);
this.updateColor();
}
private void updateColor() {
PotionContents potionContents = this.getPotionContents();
this.entityData.set(ID_EFFECT_COLOR, potionContents.equals(PotionContents.EMPTY) ? -1 : potionContents.getColor());
}
public void addEffect(MobEffectInstance effectInstance) {
this.setPotionContents(this.getPotionContents().withEffectAdded(effectInstance));
}
@Override
protected void defineSynchedData(Builder builder) {
super.defineSynchedData(builder);
builder.define(ID_EFFECT_COLOR, -1);
}
@Override
public void tick() {
super.tick();
if (this.level().isClientSide) {
if (this.isInGround()) {
if (this.inGroundTime % 5 == 0) {
this.makeParticle(1);
}
} else {
this.makeParticle(2);
}
} else if (this.isInGround() && this.inGroundTime != 0 && !this.getPotionContents().equals(PotionContents.EMPTY) && this.inGroundTime >= 600) {
this.level().broadcastEntityEvent(this, (byte)0);
this.setPickupItemStack(new ItemStack(Items.ARROW));
}
}
private void makeParticle(int particleAmount) {
int i = this.getColor();
if (i != -1 && particleAmount > 0) {
for (int j = 0; j < particleAmount; j++) {
this.level()
.addParticle(ColorParticleOption.create(ParticleTypes.ENTITY_EFFECT, i), this.getRandomX(0.5), this.getRandomY(), this.getRandomZ(0.5), 0.0, 0.0, 0.0);
}
}
}
public int getColor() {
return this.entityData.get(ID_EFFECT_COLOR);
}
@Override
protected void doPostHurtEffects(LivingEntity target) {
super.doPostHurtEffects(target);
Entity entity = this.getEffectSource();
PotionContents potionContents = this.getPotionContents();
float f = this.getPotionDurationScale();
potionContents.forEachEffect(mobEffectInstance -> target.addEffect(mobEffectInstance, entity), f);
}
@Override
protected ItemStack getDefaultPickupItem() {
return new ItemStack(Items.ARROW);
}
@Override
public void handleEntityEvent(byte id) {
if (id == 0) {
int i = this.getColor();
if (i != -1) {
float f = (i >> 16 & 0xFF) / 255.0F;
float g = (i >> 8 & 0xFF) / 255.0F;
float h = (i >> 0 & 0xFF) / 255.0F;
for (int j = 0; j < 20; j++) {
this.level()
.addParticle(
ColorParticleOption.create(ParticleTypes.ENTITY_EFFECT, f, g, h), this.getRandomX(0.5), this.getRandomY(), this.getRandomZ(0.5), 0.0, 0.0, 0.0
);
}
}
} else {
super.handleEntityEvent(id);
}
}
}