Created
April 30, 2020 16:41
-
-
Save Vatuu/a6ab9c759bd813be9b0ee5e49e109d99 to your computer and use it in GitHub Desktop.
A entity template for spellcasting entities, with a spell registry and all.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import net.minecraft.entity.EntityType; | |
import net.minecraft.entity.LivingEntity; | |
import net.minecraft.entity.ai.goal.Goal; | |
import net.minecraft.entity.data.DataTracker; | |
import net.minecraft.entity.data.TrackedData; | |
import net.minecraft.entity.data.TrackedDataHandler; | |
import net.minecraft.entity.data.TrackedDataHandlerRegistry; | |
import net.minecraft.entity.mob.HostileEntity; | |
import net.minecraft.nbt.CompoundTag; | |
import net.minecraft.network.PacketByteBuf; | |
import net.minecraft.sound.SoundEvent; | |
import net.minecraft.util.Identifier; | |
import net.minecraft.world.World; | |
import javax.management.InvalidAttributeValueException; | |
import java.util.HashMap; | |
import java.util.function.Consumer; | |
public abstract class SpellcastingEntity extends HostileEntity { | |
private Spell spell; | |
private int spellTicks; | |
public SpellcastingEntity(EntityType<? extends SpellcastingEntity> type, World w) { | |
super(type, w); | |
this.spell = Spell.NONE; | |
} | |
protected abstract SoundEvent getCastSpellSound(); | |
protected void initDataTracker() { | |
super.initDataTracker(); | |
this.dataTracker.startTracking(SPELL, Spell.NONE); | |
} | |
public void readCustomDataFromTag(CompoundTag tag) { | |
super.readCustomDataFromTag(tag); | |
this.spellTicks = tag.getInt("SpellTicks"); | |
} | |
public void writeCustomDataToTag(CompoundTag tag) { | |
super.writeCustomDataToTag(tag); | |
tag.putInt("SpellTicks", this.spellTicks); | |
} | |
public boolean isSpellcasting() { | |
if (this.world.isClient) { | |
return !this.dataTracker.get(SPELL).equals(Spell.NONE); | |
} else { | |
return this.spellTicks > 0; | |
} | |
} | |
public void setSpell(Spell spell) { | |
this.spell = spell; | |
this.dataTracker.set(SPELL, spell); | |
} | |
protected Spell getSpell() { | |
return !this.world.isClient ? this.spell : this.dataTracker.get(SPELL); | |
} | |
protected void mobTick() { | |
super.mobTick(); | |
if (this.spellTicks > 0) | |
--this.spellTicks; | |
} | |
public void tick() { | |
super.tick(); | |
if (this.world.isClient && this.isSpellcasting()) | |
this.getSpell().spellEffect.accept(this); | |
} | |
public static final class SpellRegistry { | |
private static final HashMap<Identifier, Spell> spells = new HashMap<>(); | |
public static Spell get(Identifier spell) { | |
try { | |
return spells.values().stream() | |
.filter(s -> s.getId().equals(spell)) | |
.findFirst() | |
.orElseThrow(() -> new InvalidAttributeValueException(String.format("Trying to get unknown spell! [%s]", spell))); | |
} catch (InvalidAttributeValueException e) { | |
e.printStackTrace(); | |
return null; | |
} | |
} | |
public static boolean registerSpell(Spell spell) { | |
if(spells.containsKey(spell.getId())) | |
return false; | |
else { | |
spells.put(spell.getId(), spell); | |
return true; | |
} | |
} | |
static { registerSpell(Spell.NONE); } | |
} | |
public static class Spell { | |
public static final Spell NONE = new Spell(new Identifier("tessebase", "none"), (e) -> {}); | |
private final Identifier id; | |
private final Consumer<SpellcastingEntity> spellEffect; | |
public Spell(Identifier id, Consumer<SpellcastingEntity> t) { | |
this.id = id; | |
this.spellEffect = t; | |
} | |
public Identifier getId() { | |
return id; | |
} | |
public boolean equals(Object o) { | |
if(!(o instanceof Spell)) | |
return false; | |
else | |
return ((Spell)o).getId().equals(id); | |
} | |
} | |
public abstract class CastSpellGoal extends Goal { | |
protected int spellCooldown; | |
protected int startTime; | |
protected CastSpellGoal() { } | |
public boolean canStart() { | |
LivingEntity livingEntity = SpellcastingEntity.this.getTarget(); | |
if (livingEntity != null && livingEntity.isAlive()) { | |
if (SpellcastingEntity.this.isSpellcasting()) | |
return false; | |
else | |
return SpellcastingEntity.this.age >= this.startTime; | |
} else | |
return false; | |
} | |
public boolean shouldContinue() { | |
LivingEntity livingEntity = SpellcastingEntity.this.getTarget(); | |
return livingEntity != null && livingEntity.isAlive() && this.spellCooldown > 0; | |
} | |
public void start() { | |
this.spellCooldown = this.getInitialCooldown(); | |
SpellcastingEntity.this.spellTicks = this.getSpellTicks(); | |
this.startTime = SpellcastingEntity.this.age + this.startTimeDelay(); | |
SoundEvent soundEvent = this.getSoundPrepare(); | |
if (soundEvent != null) | |
SpellcastingEntity.this.playSound(soundEvent, 1.0F, 1.0F); | |
SpellcastingEntity.this.setSpell(this.getSpell()); | |
} | |
public void tick() { | |
--this.spellCooldown; | |
if (this.spellCooldown == 0) { | |
this.castSpell(); | |
SpellcastingEntity.this.playSound(SpellcastingEntity.this.getCastSpellSound(), 1.0F, 1.0F); | |
} | |
} | |
protected int getInitialCooldown() { | |
return 20; | |
} | |
protected abstract void castSpell(); | |
protected abstract int getSpellTicks(); | |
protected abstract int startTimeDelay(); | |
protected abstract SoundEvent getSoundPrepare(); | |
protected abstract Spell getSpell(); | |
} | |
private static final TrackedDataHandler<Spell> TRACKED_SPELL = new TrackedDataHandler<Spell>() { | |
@Override | |
public void write(PacketByteBuf data, Spell spell) { | |
data.writeString(spell.getId().toString()); | |
} | |
@Override | |
public Spell read(PacketByteBuf buf) { | |
return SpellRegistry.get(new Identifier(buf.readString())); | |
} | |
@Override | |
public Spell copy(Spell spell) { | |
return spell; | |
} | |
}; | |
private static final TrackedData<Spell> SPELL = DataTracker.registerData(SpellcastingEntity.class, TRACKED_SPELL); | |
static { | |
TrackedDataHandlerRegistry.register(TRACKED_SPELL); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment