Source GhastInfo - Spiderman31807/Mob_Selector_Mod GitHub Wiki

package playasmob;

import net.minecraft.world.phys.Vec3;
import net.minecraft.world.level.biome.Biomes;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.projectile.LargeFireball;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.monster.Ghast;
import net.minecraft.world.entity.monster.Enemy;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.tags.DamageTypeTags;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.resources.ResourceKey;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.client.renderer.entity.state.GhastRenderState;
import net.minecraft.client.renderer.entity.state.EntityRenderState;
import net.minecraft.client.renderer.entity.GhastRenderer;
import net.minecraft.client.renderer.entity.EntityRenderer;

import java.util.List;

public class GhastInfo extends FlyingMobInfo implements Enemy {
	public static final Synched chargeTime = Synched.ChargeTime;
	public static final Synched charge = Synched.Charge;
	public static final Synched firing = Synched.Firing;
	public int explosionPower = 1;

	public GhastInfo(Player player, CompoundTag compound) {
		super(EntityType.GHAST, Ghast.class, player, compound);
	}

	public GhastInfo(Player player) {
		this(player, null);
	}

	public GhastInfo() {
		this(null);
	}

	// Custom Code
	
	@Override
	public void reset() {
		super.reset();
		this.reset(chargeTime);
		this.reset(charge);
		this.reset(firing);
	}

	@Override
	public EntityRenderer getRenderer() {
		return new GhastRenderer(Utils.getContext());
	}

	@Override
	public EntityRenderState createState() {
		return new GhastRenderState();
	}

	@Override
	public void modifyState(EntityRenderState state) {
		super.modifyState(state);
		if (state instanceof GhastRenderState ghastState)
			ghastState.isCharging = this.isCharging();
	}

	@Override
	public void press(int key, boolean pressed, int time) {
		if (key == 1)
			this.set(firing, pressed);
	}

	@Override
	public List<HudIcon> getIcons(float partialTick) {
		if(this.isSpectator())
			return super.getIcons(partialTick);
		int cooldown = Math.max((this.<Integer>get(chargeTime) * -1) / 20, 0);
		HudIcon attack = new HudIcon("textures/item/fire_charge.png").key(Keybinds.Key1).using(this.get(firing)).useable(cooldown == 0).countdown(cooldown);
		return Utils.merge(super.getIcons(partialTick), List.of(attack));
	}

	@Override
	public float getMaxHeadRotationRelativeToBody(float original) {
		return 0;
	}

	@Override
	public boolean serverAiStep(Object object) {
		if (!super.serverAiStep(null))
			return false;
		if (this.isClient() || this.isSpectator())
			return true;

		int time = this.get(chargeTime);
		if (time < 0 || this.<Boolean>get(firing))
			this.set(chargeTime, time + 1);
		if (!this.<Boolean>get(firing)) {
			if (time > 0)
				this.set(chargeTime, time - 1);
			this.setCharging(time > 10);
			return true;
		}

		if (time == 10 && !this.isSilent())
			this.level().levelEvent(null, 1015, this.blockPosition(), 0);
		if (time == 20) {
			if (!this.isSilent())
				this.level().levelEvent(null, 1016, this.blockPosition(), 0);
			Vec3 viewPoint = this.getViewVector(1);
			LargeFireball fireball = new LargeFireball(this.level(), this.player, Utils.getFacingImpluse(this.player).normalize(), this.getExplosionPower());
			fireball.setPos(this.getX() + viewPoint.x * 4.0, this.getY(0.5) + 0.5, fireball.getZ() + viewPoint.z * 4.0);
			this.level().addFreshEntity(fireball);
			this.set(chargeTime, -40);
		}
		this.setCharging(time > 10);
		return true;
	}

	@Override
	public ResourceKey<Level> getRespawnDimension() {
		return Level.NETHER;
	}

	@Override
	public List<ResourceKey<Biome>> getRespawnBiomes(ResourceKey<Level> dimension) {
		return dimension.equals(Level.NETHER) ? List.of(Biomes.BASALT_DELTAS, Biomes.NETHER_WASTES, Biomes.SOUL_SAND_VALLEY) : super.getRespawnBiomes(dimension);
	}

	// Ghast.class Code
	public boolean isCharging() {
		return this.get(charge);
	}

	public void setCharging(boolean charging) {
		this.set(charge, charging);
	}

	public int getExplosionPower() {
		return this.explosionPower + 1;
	}

	public boolean isReflectedFireball(DamageSource source) {
		return source.getDirectEntity() instanceof LargeFireball && source.getEntity() instanceof Player player && !player.equals(this.player);
	}

	@Override
	public boolean isInvulnerableTo(boolean original, ServerLevel server, DamageSource source) {
		return this.isInvulnerable() && !source.is(DamageTypeTags.BYPASSES_INVULNERABILITY) || !isReflectedFireball(source) && super.isInvulnerableTo(original, server, source);
	}

	@Override
	public boolean hurtServer(boolean original, ServerLevel server, DamageSource source, float damage) {
		if (this.isReflectedFireball(source))
			return super.hurtServer(original, server, source, 1000);
		return this.isInvulnerableTo(server, source) ? false : super.hurtServer(original, server, source, damage);
	}

	@Override
	public SoundSource getSoundSource() {
		return SoundSource.HOSTILE;
	}

	@Override
	public SoundEvent getAmbientSound() {
		return SoundEvents.GHAST_AMBIENT;
	}

	@Override
	public SoundEvent getHurtSound(SoundEvent original, DamageSource source) {
		return SoundEvents.GHAST_HURT;
	}

	@Override
	public SoundEvent getDeathSound(SoundEvent original) {
		return SoundEvents.GHAST_DEATH;
	}

	@Override
	public float getSoundVolume(float original) {
		return 5;
	}

	@Override
	public CompoundTag saveData() {
		CompoundTag compound = super.saveData();
		compound.putByte("ExplosionPower", (byte) this.explosionPower);
		return compound;
	}

	@Override
	public void loadData(CompoundTag compound) {
		super.loadData(compound);
		if (compound.contains("ExplosionPower", 99))
			this.explosionPower = compound.getByte("ExplosionPower");
	}
}
⚠️ **GitHub.com Fallback** ⚠️