2021-03-04 21:35:49 +01:00
|
|
|
package com.minelittlepony.unicopia.entity;
|
|
|
|
|
|
|
|
import java.util.Optional;
|
|
|
|
import java.util.UUID;
|
|
|
|
|
|
|
|
import com.minelittlepony.unicopia.Affinity;
|
|
|
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
|
|
|
import com.minelittlepony.unicopia.ability.magic.Levelled;
|
|
|
|
import com.minelittlepony.unicopia.ability.magic.Spell;
|
2021-03-05 18:22:09 +01:00
|
|
|
import com.minelittlepony.unicopia.ability.magic.SpellContainer;
|
2021-03-04 21:35:49 +01:00
|
|
|
import com.minelittlepony.unicopia.ability.magic.spell.AbstractPlacedSpell;
|
|
|
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellPredicate;
|
|
|
|
import com.minelittlepony.unicopia.network.Channel;
|
|
|
|
import com.minelittlepony.unicopia.network.MsgSpawnProjectile;
|
|
|
|
|
|
|
|
import net.minecraft.entity.Entity;
|
|
|
|
import net.minecraft.entity.EntityType;
|
|
|
|
import net.minecraft.entity.LivingEntity;
|
|
|
|
import net.minecraft.entity.data.DataTracker;
|
|
|
|
import net.minecraft.entity.data.TrackedData;
|
|
|
|
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
|
2021-08-04 15:38:03 +02:00
|
|
|
import net.minecraft.nbt.NbtCompound;
|
2021-03-04 21:35:49 +01:00
|
|
|
import net.minecraft.network.Packet;
|
2021-03-06 13:27:52 +01:00
|
|
|
import net.minecraft.text.Text;
|
|
|
|
import net.minecraft.text.TranslatableText;
|
2021-03-05 19:52:49 +01:00
|
|
|
import net.minecraft.util.math.BlockPos;
|
2021-03-04 21:35:49 +01:00
|
|
|
import net.minecraft.world.World;
|
|
|
|
|
|
|
|
public class CastSpellEntity extends Entity implements Caster<LivingEntity> {
|
|
|
|
|
|
|
|
private static final TrackedData<Float> GRAVITY = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
|
|
|
|
|
|
|
private static final TrackedData<Optional<UUID>> SPELL = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.OPTIONAL_UUID);
|
|
|
|
|
|
|
|
private static final SpellPredicate<AbstractPlacedSpell> SPELL_TYPE = s -> s instanceof AbstractPlacedSpell;
|
|
|
|
|
|
|
|
private static final LevelStore LEVELS = Levelled.fixed(0);
|
|
|
|
|
|
|
|
private final EntityPhysics<CastSpellEntity> physics = new EntityPhysics<>(this, GRAVITY);
|
|
|
|
|
2021-03-04 22:30:43 +01:00
|
|
|
private final EntityReference<LivingEntity> owner = new EntityReference<>();
|
2021-03-04 21:35:49 +01:00
|
|
|
|
2021-03-05 19:52:49 +01:00
|
|
|
private BlockPos lastPos;
|
|
|
|
|
|
|
|
private int orphanedTicks;
|
|
|
|
|
2021-03-04 21:35:49 +01:00
|
|
|
public CastSpellEntity(EntityType<?> type, World world) {
|
|
|
|
super(type, world);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void initDataTracker() {
|
|
|
|
getDataTracker().startTracking(SPELL, Optional.empty());
|
|
|
|
}
|
|
|
|
|
2021-03-06 13:27:52 +01:00
|
|
|
@Override
|
|
|
|
public Text getName() {
|
|
|
|
Entity master = getMaster();
|
|
|
|
if (master != null) {
|
|
|
|
return new TranslatableText("entity.unicopia.cast_spell.by", master.getName());
|
|
|
|
}
|
|
|
|
return super.getName();
|
|
|
|
}
|
|
|
|
|
2021-03-04 21:35:49 +01:00
|
|
|
@Override
|
|
|
|
public void tick() {
|
|
|
|
super.tick();
|
|
|
|
|
2021-08-04 15:38:03 +02:00
|
|
|
if (isRemoved()) {
|
2021-03-04 21:35:49 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-03-05 19:52:49 +01:00
|
|
|
if (world.isClient) {
|
|
|
|
BlockPos currentPos = getBlockPos();
|
|
|
|
|
|
|
|
world.getLightingProvider().addLightSource(currentPos, 11);
|
|
|
|
|
|
|
|
if (lastPos != null && !currentPos.equals(lastPos)) {
|
|
|
|
world.getLightingProvider().checkBlock(lastPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
lastPos = currentPos;
|
|
|
|
}
|
2021-03-04 21:35:49 +01:00
|
|
|
LivingEntity master = getMaster();
|
|
|
|
|
2021-08-04 15:38:03 +02:00
|
|
|
if (master == null || master.isRemoved()) {
|
2021-03-05 19:52:49 +01:00
|
|
|
if (orphanedTicks-- > 0) {
|
|
|
|
return;
|
|
|
|
}
|
2021-08-04 15:38:03 +02:00
|
|
|
remove(RemovalReason.DISCARDED);
|
2021-03-04 21:35:49 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-03-05 19:52:49 +01:00
|
|
|
orphanedTicks = 0;
|
|
|
|
|
2021-03-04 21:35:49 +01:00
|
|
|
if (!Caster.of(master).filter(c -> {
|
|
|
|
UUID spellId = dataTracker.get(SPELL).orElse(null);
|
|
|
|
|
|
|
|
if (!c.getSpellSlot().get(SPELL_TYPE, true).filter(s -> s.getUuid().equals(spellId) && s.onGroundTick(this)).isPresent()) {
|
|
|
|
c.setSpell(null);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}).isPresent()) {
|
2021-08-04 15:38:03 +02:00
|
|
|
remove(RemovalReason.DISCARDED);
|
2021-03-04 21:35:49 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-05 19:52:49 +01:00
|
|
|
@Override
|
2021-08-04 15:38:03 +02:00
|
|
|
public void remove(RemovalReason reason) {
|
|
|
|
super.remove(reason);
|
2021-03-05 19:52:49 +01:00
|
|
|
if (world.isClient) {
|
|
|
|
world.getLightingProvider().checkBlock(getBlockPos());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-04 21:35:49 +01:00
|
|
|
@Override
|
|
|
|
public void setMaster(LivingEntity owner) {
|
2021-03-04 22:30:43 +01:00
|
|
|
this.owner.set(owner);
|
2021-03-04 21:35:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setSpell(Spell spell) {
|
|
|
|
getDataTracker().set(SPELL, Optional.ofNullable(spell).map(Spell::getUuid));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Entity getEntity() {
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public LivingEntity getMaster() {
|
2021-03-04 22:30:43 +01:00
|
|
|
return owner.get(world);
|
2021-03-04 21:35:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public LevelStore getLevel() {
|
|
|
|
return Caster.of(getMaster()).map(Caster::getLevel).orElse(LEVELS);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Affinity getAffinity() {
|
|
|
|
return getSpellSlot().get(true).map(Spell::getAffinity).orElse(Affinity.NEUTRAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Physics getPhysics() {
|
|
|
|
return physics;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2021-03-05 18:22:09 +01:00
|
|
|
public SpellContainer getSpellSlot() {
|
|
|
|
return Caster.of(getMaster()).map(Caster::getSpellSlot).orElse(SpellContainer.EMPTY);
|
2021-03-04 21:35:49 +01:00
|
|
|
}
|
|
|
|
|
2021-03-06 11:26:54 +01:00
|
|
|
@Override
|
|
|
|
public boolean subtractEnergyCost(double amount) {
|
|
|
|
return Caster.of(getMaster()).filter(c -> c.subtractEnergyCost(amount)).isPresent();
|
|
|
|
}
|
|
|
|
|
2021-03-04 21:35:49 +01:00
|
|
|
@Override
|
2021-08-04 15:38:03 +02:00
|
|
|
protected void writeCustomDataToNbt(NbtCompound tag) {
|
2021-03-04 22:30:43 +01:00
|
|
|
tag.put("owner", owner.toNBT());
|
2021-03-05 19:52:49 +01:00
|
|
|
dataTracker.get(SPELL).ifPresent(spellId -> {
|
|
|
|
tag.putUuid("spellId", spellId);
|
|
|
|
});
|
|
|
|
|
2021-03-04 21:35:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2021-08-04 15:38:03 +02:00
|
|
|
protected void readCustomDataFromNbt(NbtCompound tag) {
|
2021-03-04 22:30:43 +01:00
|
|
|
if (tag.contains("owner")) {
|
|
|
|
owner.fromNBT(tag.getCompound("owner"));
|
2021-03-04 21:35:49 +01:00
|
|
|
}
|
2021-03-05 19:52:49 +01:00
|
|
|
if (tag.contains("spellId")) {
|
|
|
|
dataTracker.set(SPELL, Optional.ofNullable(tag.getUuid("spellId")));
|
|
|
|
}
|
|
|
|
orphanedTicks = 60;
|
2021-03-04 21:35:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Packet<?> createSpawnPacket() {
|
|
|
|
return Channel.SERVER_SPAWN_PROJECTILE.toPacket(new MsgSpawnProjectile(this));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|