Fixed placed and projectile spells not syncing their level correctly. Also fixes placed shields not rendering

This commit is contained in:
Sollace 2024-05-22 13:58:20 +01:00
parent ca361049f5
commit e23cbcdd1c
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
6 changed files with 94 additions and 25 deletions

View file

@ -1,33 +1,32 @@
package com.minelittlepony.unicopia.ability.magic; package com.minelittlepony.unicopia.ability.magic;
import java.util.function.IntConsumer;
import java.util.function.IntSupplier; import java.util.function.IntSupplier;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.math.MathHelper;
/** /**
* Object with levelling capabilities. * Object with levelling capabilities.
*/ */
public interface Levelled { public interface Levelled {
LevelStore EMPTY = fixed(0); LevelStore ZERO = of(0, 1);
static LevelStore fixed(int level) { static LevelStore of(IntSupplier getter, IntConsumer setter, IntSupplier max) {
return of(() -> level);
}
static LevelStore of(IntSupplier supplier) {
return new LevelStore() { return new LevelStore() {
@Override @Override
public int get() { public int get() {
return supplier.getAsInt(); return getter.getAsInt();
} }
@Override @Override
public void set(int level) { public void set(int level) {
setter.accept(level);
} }
@Override @Override
public int getMax() { public int getMax() {
return get(); return max.getAsInt();
} }
}; };
} }
@ -37,7 +36,9 @@ public interface Levelled {
} }
static LevelStore fromNbt(NbtCompound compound) { static LevelStore fromNbt(NbtCompound compound) {
return of(compound.getInt("value"), compound.getInt("max")); int max = Math.max(1, compound.getInt("max"));
int value = MathHelper.clamp(compound.getInt("value"), 0, max);
return of(value, max);
} }
static LevelStore of(int level, int max) { static LevelStore of(int level, int max) {
@ -70,6 +71,9 @@ public interface Levelled {
void set(int level); void set(int level);
default float getScaled(float max) { default float getScaled(float max) {
if (getMax() == 0) {
return max;
}
return ((float)get() / getMax()) * max; return ((float)get() / getMax()) * max;
} }

View file

@ -279,12 +279,12 @@ public class Creature extends Living<LivingEntity> implements WeaklyOwned.Mutabl
@Override @Override
public LevelStore getLevel() { public LevelStore getLevel() {
return Levelled.EMPTY; return Levelled.ZERO;
} }
@Override @Override
public LevelStore getCorruption() { public LevelStore getCorruption() {
return Levelled.EMPTY; return Levelled.ZERO;
} }
@Override @Override

View file

@ -134,8 +134,8 @@ public class EntityReference<T extends Entity> implements NbtSerialisable {
entity.getPos(), entity.getPos(),
entity.getId(), entity instanceof PlayerEntity, entity.getId(), entity instanceof PlayerEntity,
!entity.isAlive(), !entity.isAlive(),
Caster.of(entity).map(Caster::getLevel).map(Levelled::copyOf).orElse(Levelled.EMPTY), Caster.of(entity).map(Caster::getLevel).map(Levelled::copyOf).orElse(Levelled.ZERO),
Caster.of(entity).map(Caster::getCorruption).map(Levelled::copyOf).orElse(Levelled.EMPTY) Caster.of(entity).map(Caster::getCorruption).map(Levelled::copyOf).orElse(Levelled.ZERO)
); );
} }

View file

@ -17,11 +17,18 @@ 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<Integer> LEVEL = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.INTEGER);
private static final TrackedData<Integer> MAX_LEVEL = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.INTEGER);
private static final TrackedData<Integer> CORRUPTION = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.INTEGER);
private static final TrackedData<Integer> MAX_CORRUPTION = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.INTEGER);
private final EntityPhysics<CastSpellEntity> physics = new EntityPhysics<>(this); private final EntityPhysics<CastSpellEntity> physics = new EntityPhysics<>(this);
@ -29,8 +36,16 @@ public class CastSpellEntity extends LightEmittingEntity implements Caster<CastS
private final EntityReference<LivingEntity> owner = new EntityReference<>(); private final EntityReference<LivingEntity> owner = new EntityReference<>();
private LevelStore level = Levelled.EMPTY; private final LevelStore level = Levelled.of(
private LevelStore corruption = Levelled.EMPTY; () -> dataTracker.get(LEVEL),
l -> dataTracker.set(LEVEL, l),
() -> dataTracker.get(MAX_LEVEL)
);
private final LevelStore corruption = Levelled.of(
() -> dataTracker.get(CORRUPTION),
l -> dataTracker.set(CORRUPTION, l),
() -> dataTracker.get(MAX_CORRUPTION)
);
public CastSpellEntity(EntityType<?> type, World world) { public CastSpellEntity(EntityType<?> type, World world) {
super(type, world); super(type, world);
@ -39,6 +54,10 @@ public class CastSpellEntity extends LightEmittingEntity implements Caster<CastS
@Override @Override
protected void initDataTracker() { protected void initDataTracker() {
dataTracker.startTracking(LEVEL, 0);
dataTracker.startTracking(CORRUPTION, 0);
dataTracker.startTracking(MAX_LEVEL, 1);
dataTracker.startTracking(MAX_CORRUPTION, 1);
} }
@Override @Override
@ -84,8 +103,10 @@ public class CastSpellEntity extends LightEmittingEntity implements Caster<CastS
} }
public void setCaster(Caster<?> caster) { public void setCaster(Caster<?> caster) {
this.level = Levelled.copyOf(caster.getLevel()); dataTracker.set(LEVEL, caster.getLevel().get());
this.corruption = Levelled.copyOf(caster.getCorruption()); dataTracker.set(MAX_LEVEL, caster.getLevel().getMax());
dataTracker.set(CORRUPTION, caster.getCorruption().get());
dataTracker.set(MAX_CORRUPTION, caster.getCorruption().getMax());
setMaster(caster); setMaster(caster);
} }
@ -144,7 +165,11 @@ public class CastSpellEntity extends LightEmittingEntity implements Caster<CastS
owner.fromNBT(tag.getCompound("owner")); owner.fromNBT(tag.getCompound("owner"));
} }
spells.getSlots().fromNBT(tag); spells.getSlots().fromNBT(tag);
level = Levelled.fromNbt(tag.getCompound("level")); var level = Levelled.fromNbt(tag.getCompound("level"));
corruption = Levelled.fromNbt(tag.getCompound("corruption")); dataTracker.set(MAX_LEVEL, level.getMax());
dataTracker.set(LEVEL, level.get());
var corruption = Levelled.fromNbt(tag.getCompound("corruption"));
dataTracker.set(MAX_CORRUPTION, corruption.getMax());
dataTracker.set(CORRUPTION, corruption.get());
} }
} }

View file

@ -4,6 +4,8 @@ import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.InteractionManager;
import com.minelittlepony.unicopia.ability.magic.Affine; import com.minelittlepony.unicopia.ability.magic.Affine;
@ -31,10 +33,25 @@ 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<Boolean> HYDROPHOBIC = DataTracker.registerData(MagicBeamEntity.class, TrackedDataHandlerRegistry.BOOLEAN); private static final TrackedData<Boolean> HYDROPHOBIC = DataTracker.registerData(MagicBeamEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
private static final TrackedData<Integer> LEVEL = DataTracker.registerData(MagicBeamEntity.class, TrackedDataHandlerRegistry.INTEGER);
private static final TrackedData<Integer> MAX_LEVEL = DataTracker.registerData(MagicBeamEntity.class, TrackedDataHandlerRegistry.INTEGER);
private static final TrackedData<Integer> CORRUPTION = DataTracker.registerData(MagicBeamEntity.class, TrackedDataHandlerRegistry.INTEGER);
private static final TrackedData<Integer> MAX_CORRUPTION = DataTracker.registerData(MagicBeamEntity.class, TrackedDataHandlerRegistry.INTEGER);
private final SpellInventory spells = SpellSlots.ofSingle(this); private final SpellInventory spells = SpellSlots.ofSingle(this);
private final EntityPhysics<MagicProjectileEntity> physics = new EntityPhysics<>(this); private final EntityPhysics<MagicProjectileEntity> physics = new EntityPhysics<>(this);
private final LevelStore level = Levelled.of(
() -> dataTracker.get(LEVEL),
l -> dataTracker.set(LEVEL, l),
() -> dataTracker.get(MAX_LEVEL)
);
private final LevelStore corruption = Levelled.of(
() -> dataTracker.get(CORRUPTION),
l -> dataTracker.set(CORRUPTION, l),
() -> dataTracker.get(MAX_CORRUPTION)
);
public MagicBeamEntity(EntityType<MagicBeamEntity> type, World world) { public MagicBeamEntity(EntityType<MagicBeamEntity> type, World world) {
super(type, world); super(type, world);
} }
@ -51,7 +68,11 @@ public class MagicBeamEntity extends MagicProjectileEntity implements Caster<Mag
@Override @Override
protected void initDataTracker() { protected void initDataTracker() {
super.initDataTracker(); super.initDataTracker();
getDataTracker().startTracking(HYDROPHOBIC, false); dataTracker.startTracking(HYDROPHOBIC, false);
dataTracker.startTracking(LEVEL, 0);
dataTracker.startTracking(CORRUPTION, 0);
dataTracker.startTracking(MAX_LEVEL, 1);
dataTracker.startTracking(MAX_CORRUPTION, 1);
} }
@Override @Override
@ -92,14 +113,25 @@ public class MagicBeamEntity extends MagicProjectileEntity implements Caster<Mag
return this; return this;
} }
@Override
public void setOwner(@Nullable Entity entity) {
super.setOwner(entity);
Caster.of(entity).ifPresent(caster -> {
dataTracker.set(LEVEL, caster.getLevel().get());
dataTracker.set(MAX_LEVEL, caster.getLevel().getMax());
dataTracker.set(CORRUPTION, caster.getCorruption().get());
dataTracker.set(MAX_CORRUPTION, caster.getCorruption().getMax());
});
}
@Override @Override
public LevelStore getLevel() { public LevelStore getLevel() {
return getMasterReference().getTarget().map(target -> target.level()).orElse(Levelled.EMPTY); return level;
} }
@Override @Override
public LevelStore getCorruption() { public LevelStore getCorruption() {
return getMasterReference().getTarget().map(target -> target.corruption()).orElse(Levelled.EMPTY); return corruption;
} }
@Override @Override
@ -149,11 +181,19 @@ public class MagicBeamEntity extends MagicProjectileEntity implements Caster<Mag
getDataTracker().set(HYDROPHOBIC, compound.getBoolean("hydrophobic")); getDataTracker().set(HYDROPHOBIC, compound.getBoolean("hydrophobic"));
physics.fromNBT(compound); physics.fromNBT(compound);
spells.getSlots().fromNBT(compound); spells.getSlots().fromNBT(compound);
var level = Levelled.fromNbt(compound.getCompound("level"));
dataTracker.set(MAX_LEVEL, level.getMax());
dataTracker.set(LEVEL, level.get());
var corruption = Levelled.fromNbt(compound.getCompound("corruption"));
dataTracker.set(MAX_CORRUPTION, corruption.getMax());
dataTracker.set(CORRUPTION, corruption.get());
} }
@Override @Override
public void writeCustomDataToNbt(NbtCompound compound) { public void writeCustomDataToNbt(NbtCompound compound) {
super.writeCustomDataToNbt(compound); super.writeCustomDataToNbt(compound);
compound.put("level", level.toNbt());
compound.put("corruption", corruption.toNbt());
compound.putBoolean("hydrophobic", getHydrophobic()); compound.putBoolean("hydrophobic", getHydrophobic());
physics.toNBT(compound); physics.toNBT(compound);
spells.getSlots().toNBT(compound); spells.getSlots().toNBT(compound);

View file

@ -78,7 +78,7 @@ public class MagicProjectileEntity extends ThrownItemEntity implements WeaklyOwn
} }
@Override @Override
public void setMaster(LivingEntity owner) { public final void setMaster(LivingEntity owner) {
setOwner(owner); setOwner(owner);
} }
@ -86,13 +86,13 @@ public class MagicProjectileEntity extends ThrownItemEntity implements WeaklyOwn
public void setOwner(@Nullable Entity entity) { public void setOwner(@Nullable Entity entity) {
super.setOwner(entity); super.setOwner(entity);
if (entity instanceof LivingEntity l) { if (entity instanceof LivingEntity l) {
getMasterReference().set(l); WeaklyOwned.Mutable.super.setMaster(l);
} }
} }
@Override @Override
@Nullable @Nullable
public Entity getOwner() { public final Entity getOwner() {
return getMaster(); return getMaster();
} }