2025-11-24 22:52:51 +03:00

240 lines
8.4 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* org.jspecify.annotations.Nullable
*/
package net.minecraft.world.entity.monster;
import java.util.EnumSet;
import java.util.function.IntFunction;
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.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.util.ByIdMap;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.monster.AbstractIllager;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.storage.ValueInput;
import net.minecraft.world.level.storage.ValueOutput;
import org.jspecify.annotations.Nullable;
public abstract class SpellcasterIllager
extends AbstractIllager {
private static final EntityDataAccessor<Byte> DATA_SPELL_CASTING_ID = SynchedEntityData.defineId(SpellcasterIllager.class, EntityDataSerializers.BYTE);
private static final int DEFAULT_SPELLCASTING_TICKS = 0;
protected int spellCastingTickCount = 0;
private IllagerSpell currentSpell = IllagerSpell.NONE;
protected SpellcasterIllager(EntityType<? extends SpellcasterIllager> type, Level level) {
super((EntityType<? extends AbstractIllager>)type, level);
}
@Override
protected void defineSynchedData(SynchedEntityData.Builder entityData) {
super.defineSynchedData(entityData);
entityData.define(DATA_SPELL_CASTING_ID, (byte)0);
}
@Override
protected void readAdditionalSaveData(ValueInput input) {
super.readAdditionalSaveData(input);
this.spellCastingTickCount = input.getIntOr("SpellTicks", 0);
}
@Override
protected void addAdditionalSaveData(ValueOutput output) {
super.addAdditionalSaveData(output);
output.putInt("SpellTicks", this.spellCastingTickCount);
}
@Override
public AbstractIllager.IllagerArmPose getArmPose() {
if (this.isCastingSpell()) {
return AbstractIllager.IllagerArmPose.SPELLCASTING;
}
if (this.isCelebrating()) {
return AbstractIllager.IllagerArmPose.CELEBRATING;
}
return AbstractIllager.IllagerArmPose.CROSSED;
}
public boolean isCastingSpell() {
if (this.level().isClientSide()) {
return this.entityData.get(DATA_SPELL_CASTING_ID) > 0;
}
return this.spellCastingTickCount > 0;
}
public void setIsCastingSpell(IllagerSpell spell) {
this.currentSpell = spell;
this.entityData.set(DATA_SPELL_CASTING_ID, (byte)spell.id);
}
protected IllagerSpell getCurrentSpell() {
if (!this.level().isClientSide()) {
return this.currentSpell;
}
return IllagerSpell.byId(this.entityData.get(DATA_SPELL_CASTING_ID).byteValue());
}
@Override
protected void customServerAiStep(ServerLevel level) {
super.customServerAiStep(level);
if (this.spellCastingTickCount > 0) {
--this.spellCastingTickCount;
}
}
@Override
public void tick() {
super.tick();
if (this.level().isClientSide() && this.isCastingSpell()) {
IllagerSpell spell = this.getCurrentSpell();
float red = (float)spell.spellColor[0];
float green = (float)spell.spellColor[1];
float blue = (float)spell.spellColor[2];
float bodyAngle = this.yBodyRot * ((float)Math.PI / 180) + Mth.cos((float)this.tickCount * 0.6662f) * 0.25f;
float cos = Mth.cos(bodyAngle);
float sin = Mth.sin(bodyAngle);
double handDistance = 0.6 * (double)this.getScale();
double handHeight = 1.8 * (double)this.getScale();
this.level().addParticle(ColorParticleOption.create(ParticleTypes.ENTITY_EFFECT, red, green, blue), this.getX() + (double)cos * handDistance, this.getY() + handHeight, this.getZ() + (double)sin * handDistance, 0.0, 0.0, 0.0);
this.level().addParticle(ColorParticleOption.create(ParticleTypes.ENTITY_EFFECT, red, green, blue), this.getX() - (double)cos * handDistance, this.getY() + handHeight, this.getZ() - (double)sin * handDistance, 0.0, 0.0, 0.0);
}
}
protected int getSpellCastingTime() {
return this.spellCastingTickCount;
}
protected abstract SoundEvent getCastingSoundEvent();
protected static enum IllagerSpell {
NONE(0, 0.0, 0.0, 0.0),
SUMMON_VEX(1, 0.7, 0.7, 0.8),
FANGS(2, 0.4, 0.3, 0.35),
WOLOLO(3, 0.7, 0.5, 0.2),
DISAPPEAR(4, 0.3, 0.3, 0.8),
BLINDNESS(5, 0.1, 0.1, 0.2);
private static final IntFunction<IllagerSpell> BY_ID;
private final int id;
private final double[] spellColor;
private IllagerSpell(int id, double red, double green, double blue) {
this.id = id;
this.spellColor = new double[]{red, green, blue};
}
public static IllagerSpell byId(int id) {
return BY_ID.apply(id);
}
static {
BY_ID = ByIdMap.continuous(e -> e.id, IllagerSpell.values(), ByIdMap.OutOfBoundsStrategy.ZERO);
}
}
protected abstract class SpellcasterUseSpellGoal
extends Goal {
protected int attackWarmupDelay;
protected int nextAttackTickCount;
protected SpellcasterUseSpellGoal() {
}
@Override
public boolean canUse() {
LivingEntity target = SpellcasterIllager.this.getTarget();
if (target == null || !target.isAlive()) {
return false;
}
if (SpellcasterIllager.this.isCastingSpell()) {
return false;
}
return SpellcasterIllager.this.tickCount >= this.nextAttackTickCount;
}
@Override
public boolean canContinueToUse() {
LivingEntity target = SpellcasterIllager.this.getTarget();
return target != null && target.isAlive() && this.attackWarmupDelay > 0;
}
@Override
public void start() {
this.attackWarmupDelay = this.adjustedTickDelay(this.getCastWarmupTime());
SpellcasterIllager.this.spellCastingTickCount = this.getCastingTime();
this.nextAttackTickCount = SpellcasterIllager.this.tickCount + this.getCastingInterval();
SoundEvent spellPrepareSound = this.getSpellPrepareSound();
if (spellPrepareSound != null) {
SpellcasterIllager.this.playSound(spellPrepareSound, 1.0f, 1.0f);
}
SpellcasterIllager.this.setIsCastingSpell(this.getSpell());
}
@Override
public void tick() {
--this.attackWarmupDelay;
if (this.attackWarmupDelay == 0) {
this.performSpellCasting();
SpellcasterIllager.this.playSound(SpellcasterIllager.this.getCastingSoundEvent(), 1.0f, 1.0f);
}
}
protected abstract void performSpellCasting();
protected int getCastWarmupTime() {
return 20;
}
protected abstract int getCastingTime();
protected abstract int getCastingInterval();
protected abstract @Nullable SoundEvent getSpellPrepareSound();
protected abstract IllagerSpell getSpell();
}
protected class SpellcasterCastingSpellGoal
extends Goal {
public SpellcasterCastingSpellGoal() {
this.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK));
}
@Override
public boolean canUse() {
return SpellcasterIllager.this.getSpellCastingTime() > 0;
}
@Override
public void start() {
super.start();
SpellcasterIllager.this.navigation.stop();
}
@Override
public void stop() {
super.stop();
SpellcasterIllager.this.setIsCastingSpell(IllagerSpell.NONE);
}
@Override
public void tick() {
if (SpellcasterIllager.this.getTarget() != null) {
SpellcasterIllager.this.getLookControl().setLookAt(SpellcasterIllager.this.getTarget(), SpellcasterIllager.this.getMaxHeadYRot(), SpellcasterIllager.this.getMaxHeadXRot());
}
}
}
}