mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 21:38:00 +01:00
Implement a custom data tracker to sync values dynamically. Fixes #14
This commit is contained in:
parent
c1bcaaa78e
commit
771da650c4
9 changed files with 47 additions and 112 deletions
|
@ -32,7 +32,9 @@ public interface SpellContainer {
|
||||||
/**
|
/**
|
||||||
* Gets the active effect for this caster updating it if needed.
|
* Gets the active effect for this caster updating it if needed.
|
||||||
*/
|
*/
|
||||||
<T extends Spell> Optional<T> get(@Nullable SpellPredicate<T> type);
|
default <T extends Spell> Optional<T> get(@Nullable SpellPredicate<T> type) {
|
||||||
|
return stream(type).findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the active effect.
|
* Sets the active effect.
|
||||||
|
@ -73,10 +75,12 @@ public interface SpellContainer {
|
||||||
/**
|
/**
|
||||||
* Gets all active effects for this caster updating it if needed.
|
* Gets all active effects for this caster updating it if needed.
|
||||||
*/
|
*/
|
||||||
Stream<Spell> stream();
|
default Stream<Spell> stream() {
|
||||||
|
return stream(null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all active effects for this caster that match the given type updating it if needed.
|
* Gets all active effects for this caster that match the given type.
|
||||||
*/
|
*/
|
||||||
<T extends Spell> Stream<T> stream(@Nullable SpellPredicate<T> type);
|
<T extends Spell> Stream<T> stream(@Nullable SpellPredicate<T> type);
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,6 @@ import net.minecraft.entity.SpawnGroup;
|
||||||
import net.minecraft.entity.ai.goal.*;
|
import net.minecraft.entity.ai.goal.*;
|
||||||
import net.minecraft.entity.attribute.DefaultAttributeContainer;
|
import net.minecraft.entity.attribute.DefaultAttributeContainer;
|
||||||
import net.minecraft.entity.attribute.EntityAttributes;
|
import net.minecraft.entity.attribute.EntityAttributes;
|
||||||
import net.minecraft.entity.data.TrackedData;
|
|
||||||
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
|
|
||||||
import net.minecraft.entity.mob.*;
|
import net.minecraft.entity.mob.*;
|
||||||
import net.minecraft.entity.passive.*;
|
import net.minecraft.entity.passive.*;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
@ -41,7 +39,6 @@ import net.minecraft.nbt.NbtElement;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
public class Creature extends Living<LivingEntity> implements WeaklyOwned.Mutable<LivingEntity> {
|
public class Creature extends Living<LivingEntity> implements WeaklyOwned.Mutable<LivingEntity> {
|
||||||
static final TrackedData<NbtCompound> EFFECT = net.minecraft.entity.data.DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND);
|
|
||||||
public static void boostrap() {}
|
public static void boostrap() {}
|
||||||
|
|
||||||
private final EntityPhysics<LivingEntity> physics;
|
private final EntityPhysics<LivingEntity> physics;
|
||||||
|
|
|
@ -19,8 +19,6 @@ public interface Equine<T extends Entity> extends NbtSerialisable, Tickable, Pro
|
||||||
|
|
||||||
void setSpecies(Race race);
|
void setSpecies(Race race);
|
||||||
|
|
||||||
void initDataTracker();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called at the beginning of an update cycle.
|
* Called at the beginning of an update cycle.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -47,10 +47,6 @@ public class ItemImpl implements Equine<ItemEntity> {
|
||||||
race = tracker.startTracking(TrackableDataType.of(Race.PACKET_CODEC), Race.HUMAN);
|
race = tracker.startTracking(TrackableDataType.of(Race.PACKET_CODEC), Race.HUMAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initDataTracker() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onProjectileImpact(ProjectileEntity projectile) {
|
public boolean onProjectileImpact(ProjectileEntity projectile) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -76,8 +76,6 @@ import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
public abstract class Living<T extends LivingEntity> implements Equine<T>, Caster<T>, Transmittable {
|
public abstract class Living<T extends LivingEntity> implements Equine<T>, Caster<T>, Transmittable {
|
||||||
//private static final TrackedData<Optional<UUID>> CARRIER_ID = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.OPTIONAL_UUID);
|
|
||||||
|
|
||||||
protected final T entity;
|
protected final T entity;
|
||||||
|
|
||||||
private final EffectSync effectDelegate;
|
private final EffectSync effectDelegate;
|
||||||
|
@ -113,7 +111,7 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
this.trackers = Trackable.of(entity).getDataTrackers();
|
this.trackers = Trackable.of(entity).getDataTrackers();
|
||||||
this.tracker = trackers.getPrimaryTracker();
|
this.tracker = trackers.getPrimaryTracker();
|
||||||
this.effectDelegate = new EffectSync(this, Creature.EFFECT);
|
this.effectDelegate = new EffectSync(this, tracker);
|
||||||
this.sneakingHeuristic = addTicker(new Interactable(entity::isSneaking));
|
this.sneakingHeuristic = addTicker(new Interactable(entity::isSneaking));
|
||||||
this.landedHeuristic = addTicker(new Interactable(entity::isOnGround));
|
this.landedHeuristic = addTicker(new Interactable(entity::isOnGround));
|
||||||
this.jumpingHeuristic = addTicker(new Interactable(((LivingEntityDuck)entity)::isJumping));
|
this.jumpingHeuristic = addTicker(new Interactable(((LivingEntityDuck)entity)::isJumping));
|
||||||
|
@ -121,11 +119,6 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
||||||
carrierId = tracker.startTracking(TrackableDataType.of(PacketCodec.UUID), Util.NIL_UUID);
|
carrierId = tracker.startTracking(TrackableDataType.of(PacketCodec.UUID), Util.NIL_UUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initDataTracker() {
|
|
||||||
entity.getDataTracker().startTracking(Creature.EFFECT, new NbtCompound());
|
|
||||||
}
|
|
||||||
|
|
||||||
public <Q extends Tickable> Q addTicker(Q tickable) {
|
public <Q extends Tickable> Q addTicker(Q tickable) {
|
||||||
tickers.add(Objects.requireNonNull(tickable, "tickable cannot be null"));
|
tickers.add(Objects.requireNonNull(tickable, "tickable cannot be null"));
|
||||||
return tickable;
|
return tickable;
|
||||||
|
|
|
@ -19,19 +19,15 @@ import net.minecraft.entity.EntityDimensions;
|
||||||
import net.minecraft.entity.EntityPose;
|
import net.minecraft.entity.EntityPose;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.data.DataTracker;
|
|
||||||
import net.minecraft.entity.data.TrackedData;
|
|
||||||
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
|
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class CastSpellEntity extends LightEmittingEntity implements Caster<CastSpellEntity>, WeaklyOwned.Mutable<LivingEntity>, MagicImmune {
|
public class CastSpellEntity extends LightEmittingEntity implements Caster<CastSpellEntity>, WeaklyOwned.Mutable<LivingEntity>, MagicImmune {
|
||||||
private static final TrackedData<NbtCompound> EFFECT = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND);
|
|
||||||
|
|
||||||
private final EntityPhysics<CastSpellEntity> physics = new EntityPhysics<>(this, Trackable.of(this).getDataTrackers().getPrimaryTracker());
|
private final EntityPhysics<CastSpellEntity> physics = new EntityPhysics<>(this, Trackable.of(this).getDataTrackers().getPrimaryTracker());
|
||||||
|
|
||||||
private final EffectSync effectDelegate = new EffectSync(this, EFFECT);
|
private final EffectSync effectDelegate = new EffectSync(this, Trackable.of(this).getDataTrackers().getPrimaryTracker());
|
||||||
|
|
||||||
private final EntityReference<LivingEntity> owner = new EntityReference<>();
|
private final EntityReference<LivingEntity> owner = new EntityReference<>();
|
||||||
|
|
||||||
|
@ -45,7 +41,6 @@ public class CastSpellEntity extends LightEmittingEntity implements Caster<CastS
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initDataTracker() {
|
protected void initDataTracker() {
|
||||||
getDataTracker().startTracking(EFFECT, new NbtCompound());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -30,7 +30,6 @@ import net.minecraft.fluid.Fluid;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.registry.tag.TagKey;
|
import net.minecraft.registry.tag.TagKey;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
|
||||||
|
|
||||||
@Mixin(Entity.class)
|
@Mixin(Entity.class)
|
||||||
abstract class MixinEntity implements EntityDuck, Trackable {
|
abstract class MixinEntity implements EntityDuck, Trackable {
|
||||||
|
@ -80,14 +79,6 @@ abstract class MixinEntity implements EntityDuck, Trackable {
|
||||||
return self.hasVehicle() && self.getVehicle() instanceof LavaAffine affine && affine.isLavaAffine();
|
return self.hasVehicle() && self.getVehicle() instanceof LavaAffine affine && affine.isLavaAffine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At(value = "INVOKE", target = "net/minecraft/entity/Entity.initDataTracker()V"))
|
|
||||||
private void onInstanceInit(EntityType<?> type, World world, CallbackInfo info) {
|
|
||||||
if (this instanceof Equine.Container c) {
|
|
||||||
c.get().initDataTracker();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "isFireImmune", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "isFireImmune", at = @At("HEAD"), cancellable = true)
|
||||||
private void onIsFireImmune(CallbackInfoReturnable<Boolean> info) {
|
private void onIsFireImmune(CallbackInfoReturnable<Boolean> info) {
|
||||||
if (isLavaAffine() || (this instanceof Equine.Container c) && c.get().getCompositeRace().includes(Race.KIRIN)) {
|
if (isLavaAffine() || (this instanceof Equine.Container c) && c.get().getCompositeRace().includes(Race.KIRIN)) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.minelittlepony.unicopia.network.datasync;
|
package com.minelittlepony.unicopia.network.datasync;
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -14,9 +14,11 @@ import com.minelittlepony.unicopia.ability.magic.SpellContainer;
|
||||||
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||||
|
import com.minelittlepony.unicopia.network.track.DataTracker;
|
||||||
|
import com.minelittlepony.unicopia.network.track.TrackableDataType;
|
||||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||||
|
import com.minelittlepony.unicopia.util.serialization.PacketCodec;
|
||||||
|
|
||||||
import net.minecraft.entity.data.TrackedData;
|
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,19 +34,21 @@ public class EffectSync implements SpellContainer, NbtSerialisable {
|
||||||
|
|
||||||
private final Caster<?> owner;
|
private final Caster<?> owner;
|
||||||
|
|
||||||
private final TrackedData<NbtCompound> param;
|
private final DataTracker tracker;
|
||||||
|
private final DataTracker.Entry<NbtCompound> param;
|
||||||
|
|
||||||
@Nullable
|
public EffectSync(Caster<?> owner, DataTracker tracker) {
|
||||||
private NbtCompound lastValue;
|
|
||||||
|
|
||||||
public EffectSync(Caster<?> owner, TrackedData<NbtCompound> param) {
|
|
||||||
spells = new NetworkedReferenceSet<>(Spell::getUuid, () -> new SpellNetworkedReference<>(owner));
|
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.param = param;
|
this.tracker = tracker;
|
||||||
}
|
this.param = tracker.startTracking(TrackableDataType.of(PacketCodec.NBT), new NbtCompound());
|
||||||
|
spells = new NetworkedReferenceSet<>(Spell::getUuid, () -> new SpellNetworkedReference<>(owner));
|
||||||
|
|
||||||
public void initDataTracker() {
|
tracker.onBeforeSend(param, () -> {
|
||||||
owner.asEntity().getDataTracker().startTracking(param, new NbtCompound());
|
if (spells.isDirty()) {
|
||||||
|
tracker.set(param, spells.toNbt());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tracker.onReceive(param, nbt -> spells.fromNbt(nbt));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean tick(Situation situation) {
|
public boolean tick(Situation situation) {
|
||||||
|
@ -78,20 +82,9 @@ public class EffectSync implements SpellContainer, NbtSerialisable {
|
||||||
return spells.containsReference(id) || spells.getReferences().anyMatch(s -> s.equalsOrContains(id));
|
return spells.containsReference(id) || spells.getReferences().anyMatch(s -> s.equalsOrContains(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean contains(@Nullable SpellPredicate<?> type) {
|
|
||||||
return read(type).findFirst().isPresent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T extends Spell> Optional<T> get(@Nullable SpellPredicate<T> type) {
|
|
||||||
return read(type).findFirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void put(@Nullable Spell effect) {
|
public void put(@Nullable Spell effect) {
|
||||||
spells.addReference(effect);
|
spells.addReference(effect);
|
||||||
write();
|
|
||||||
if (owner instanceof UpdateCallback callback) {
|
if (owner instanceof UpdateCallback callback) {
|
||||||
callback.onSpellSet(effect);
|
callback.onSpellSet(effect);
|
||||||
}
|
}
|
||||||
|
@ -99,12 +92,7 @@ public class EffectSync implements SpellContainer, NbtSerialisable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(UUID id) {
|
public void remove(UUID id) {
|
||||||
Spell spell = spells.getReference(id);
|
discard(spells.getReference(id));
|
||||||
spell.setDead();
|
|
||||||
spell.tickDying(owner);
|
|
||||||
if (spell.isDead()) {
|
|
||||||
spells.removeReference(id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -113,13 +101,19 @@ public class EffectSync implements SpellContainer, NbtSerialisable {
|
||||||
if (!test.test(spell)) {
|
if (!test.test(spell)) {
|
||||||
return initial;
|
return initial;
|
||||||
}
|
}
|
||||||
|
discard(spell);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void discard(Spell spell) {
|
||||||
|
if (spell != null) {
|
||||||
spell.setDead();
|
spell.setDead();
|
||||||
spell.tickDying(owner);
|
spell.tickDying(owner);
|
||||||
if (spell.isDead()) {
|
if (spell.isDead()) {
|
||||||
spells.removeReference(spell);
|
spells.removeReference(spell);
|
||||||
}
|
}
|
||||||
return true;
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -135,55 +129,28 @@ public class EffectSync implements SpellContainer, NbtSerialisable {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@SuppressWarnings("unchecked")
|
||||||
public Stream<Spell> stream() {
|
|
||||||
return stream(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Spell> Stream<T> stream(@Nullable SpellPredicate<T> type) {
|
public <T extends Spell> Stream<T> stream(@Nullable SpellPredicate<T> type) {
|
||||||
return read(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean clear() {
|
|
||||||
if (spells.clear()) {
|
|
||||||
write();
|
|
||||||
if (owner instanceof UpdateCallback) {
|
|
||||||
((UpdateCallback)owner).onSpellSet(null);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private <T extends Spell> Stream<T> read(@Nullable SpellPredicate<T> type) {
|
|
||||||
if (owner.isClient()) {
|
|
||||||
spells.fromNbt(owner.asEntity().getDataTracker().get(param));
|
|
||||||
}
|
|
||||||
write();
|
|
||||||
|
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
return (Stream<T>)spells.getReferences();
|
return (Stream<T>)spells.getReferences();
|
||||||
}
|
}
|
||||||
return (Stream<T>)spells.getReferences().flatMap(s -> s.findMatches(type));
|
return (Stream<T>)spells.getReferences().flatMap(s -> s.findMatches(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean reduce(Alteration alteration) {
|
@Override
|
||||||
boolean initial = false;
|
public boolean clear() {
|
||||||
for (Spell i : read(null).toList()) {
|
if (spells.clear()) {
|
||||||
initial = alteration.apply(initial, i);
|
if (owner instanceof UpdateCallback c) {
|
||||||
|
c.onSpellSet(null);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
write();
|
private boolean reduce(BiFunction<Boolean, Spell, Boolean> alteration) {
|
||||||
return initial;
|
return stream().toList().stream().reduce(false, alteration, (a, b) -> b);
|
||||||
}
|
|
||||||
|
|
||||||
private void write() {
|
|
||||||
if (spells.isDirty() && !owner.isClient()) {
|
|
||||||
owner.asEntity().getDataTracker().set(param, spells.toNbt());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -194,14 +161,10 @@ public class EffectSync implements SpellContainer, NbtSerialisable {
|
||||||
@Override
|
@Override
|
||||||
public void fromNBT(NbtCompound compound) {
|
public void fromNBT(NbtCompound compound) {
|
||||||
spells.fromNbt(compound.getCompound("spells"));
|
spells.fromNbt(compound.getCompound("spells"));
|
||||||
owner.asEntity().getDataTracker().set(param, spells.toNbt());
|
tracker.set(param, spells.toNbt());
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface UpdateCallback {
|
public interface UpdateCallback {
|
||||||
void onSpellSet(@Nullable Spell spell);
|
void onSpellSet(@Nullable Spell spell);
|
||||||
}
|
}
|
||||||
|
|
||||||
private interface Alteration {
|
|
||||||
boolean apply(boolean initial, Spell spell);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,10 +32,9 @@ import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class MagicBeamEntity extends MagicProjectileEntity implements Caster<MagicBeamEntity>, MagicImmune {
|
public class MagicBeamEntity extends MagicProjectileEntity implements Caster<MagicBeamEntity>, MagicImmune {
|
||||||
private static final TrackedData<NbtCompound> EFFECT = DataTracker.registerData(MagicBeamEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND);
|
|
||||||
private static final TrackedData<Boolean> HYDROPHOBIC = DataTracker.registerData(MagicBeamEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
|
private static final TrackedData<Boolean> HYDROPHOBIC = DataTracker.registerData(MagicBeamEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
|
||||||
|
|
||||||
private final EffectSync effectDelegate = new EffectSync(this, EFFECT);
|
private final EffectSync effectDelegate = new EffectSync(this, Trackable.of(this).getDataTrackers().getPrimaryTracker());
|
||||||
private final EntityPhysics<MagicProjectileEntity> physics = new EntityPhysics<>(this, Trackable.of(this).getDataTrackers().getPrimaryTracker());
|
private final EntityPhysics<MagicProjectileEntity> physics = new EntityPhysics<>(this, Trackable.of(this).getDataTrackers().getPrimaryTracker());
|
||||||
|
|
||||||
public MagicBeamEntity(EntityType<MagicBeamEntity> type, World world) {
|
public MagicBeamEntity(EntityType<MagicBeamEntity> type, World world) {
|
||||||
|
@ -55,7 +54,6 @@ public class MagicBeamEntity extends MagicProjectileEntity implements Caster<Mag
|
||||||
protected void initDataTracker() {
|
protected void initDataTracker() {
|
||||||
super.initDataTracker();
|
super.initDataTracker();
|
||||||
getDataTracker().startTracking(HYDROPHOBIC, false);
|
getDataTracker().startTracking(HYDROPHOBIC, false);
|
||||||
getDataTracker().startTracking(EFFECT, new NbtCompound());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in a new issue