mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Sync all spells onto the ether
This commit is contained in:
parent
77de42dd09
commit
8a093a8a8b
16 changed files with 154 additions and 111 deletions
|
@ -6,6 +6,8 @@ import java.util.stream.Stream;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||||
|
import com.minelittlepony.unicopia.server.world.Ether;
|
||||||
|
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
|
||||||
public abstract class AbstractDelegatingSpell implements Spell {
|
public abstract class AbstractDelegatingSpell implements Spell {
|
||||||
|
@ -101,6 +103,9 @@ public abstract class AbstractDelegatingSpell implements Spell {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onDestroyed(Caster<?> caster) {
|
protected void onDestroyed(Caster<?> caster) {
|
||||||
|
if (!caster.isClient()) {
|
||||||
|
Ether.get(caster.asWorld()).remove(this, caster);
|
||||||
|
}
|
||||||
if (delegate.get() instanceof Spell s) {
|
if (delegate.get() instanceof Spell s) {
|
||||||
s.destroy(caster);
|
s.destroy(caster);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,11 @@ public abstract class AbstractDisguiseSpell extends AbstractSpell implements Dis
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroyed(Caster<?> caster) {
|
protected void onDestroyed(Caster<?> caster) {
|
||||||
|
super.onDestroyed(caster);
|
||||||
caster.asEntity().calculateDimensions();
|
caster.asEntity().calculateDimensions();
|
||||||
caster.asEntity().setInvisible(false);
|
caster.asEntity().setInvisible(false);
|
||||||
if (caster instanceof Pony) {
|
if (caster instanceof Pony pony) {
|
||||||
((Pony) caster).setInvisible(false);
|
pony.setInvisible(false);
|
||||||
}
|
}
|
||||||
disguise.remove();
|
disguise.remove();
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,16 +51,6 @@ public class PlaceableSpell extends AbstractDelegatingSpell implements OrientedS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Caster<?> caster) {
|
|
||||||
boolean result = super.apply(caster);
|
|
||||||
if (result && !caster.isClient()) {
|
|
||||||
Ether.get(caster.asWorld()).getOrCreate(this, caster);
|
|
||||||
}
|
|
||||||
setDirty();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getAge(float tickDelta) {
|
public float getAge(float tickDelta) {
|
||||||
return MathHelper.lerp(tickDelta, prevAge, age);
|
return MathHelper.lerp(tickDelta, prevAge, age);
|
||||||
}
|
}
|
||||||
|
@ -91,9 +81,16 @@ public class PlaceableSpell extends AbstractDelegatingSpell implements OrientedS
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tick(Caster<?> source, Situation situation) {
|
public boolean tick(Caster<?> source, Situation situation) {
|
||||||
if (!source.isClient() && !checkConnection(source)) {
|
if (!source.isClient()) {
|
||||||
setDead();
|
if (!checkConnection(source)) {
|
||||||
return false;
|
setDead();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var entry = Ether.get(source.asWorld()).get(this, source);
|
||||||
|
if (entry != null && entry.hasChanged()) {
|
||||||
|
setOrientation(source, entry.getPitch(), entry.getYaw());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prevAge = age;
|
prevAge = age;
|
||||||
|
@ -115,14 +112,6 @@ public class PlaceableSpell extends AbstractDelegatingSpell implements OrientedS
|
||||||
deathTicks--;
|
deathTicks--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroyed(Caster<?> source) {
|
|
||||||
if (!source.isClient()) {
|
|
||||||
Ether.get(source.asWorld()).remove(this, source);
|
|
||||||
}
|
|
||||||
super.onDestroyed(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setOrientation(Caster<?> caster, float pitch, float yaw) {
|
public void setOrientation(Caster<?> caster, float pitch, float yaw) {
|
||||||
this.pitch = -pitch - 90;
|
this.pitch = -pitch - 90;
|
||||||
|
@ -131,6 +120,15 @@ public class PlaceableSpell extends AbstractDelegatingSpell implements OrientedS
|
||||||
entity.updatePositionAndAngles(entity.getX(), entity.getY(), entity.getZ(), this.yaw, this.pitch);
|
entity.updatePositionAndAngles(entity.getX(), entity.getY(), entity.getZ(), this.yaw, this.pitch);
|
||||||
entity.setYaw(this.yaw);
|
entity.setYaw(this.yaw);
|
||||||
entity.setPitch(this.pitch);
|
entity.setPitch(this.pitch);
|
||||||
|
|
||||||
|
if (!caster.isClient()) {
|
||||||
|
var entry = Ether.get(caster.asWorld()).get(this, caster);
|
||||||
|
if (entry != null) {
|
||||||
|
entry.setPitch(pitch);
|
||||||
|
entry.setYaw(yaw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setDirty();
|
setDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,9 @@ import java.util.UUID;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.AbstractSpell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||||
import com.minelittlepony.unicopia.entity.EntityReference;
|
|
||||||
import com.minelittlepony.unicopia.entity.EntityReference.EntityValues;
|
|
||||||
import com.minelittlepony.unicopia.entity.mob.CastSpellEntity;
|
import com.minelittlepony.unicopia.entity.mob.CastSpellEntity;
|
||||||
import com.minelittlepony.unicopia.entity.mob.UEntities;
|
import com.minelittlepony.unicopia.entity.mob.UEntities;
|
||||||
import com.minelittlepony.unicopia.server.world.Ether;
|
import com.minelittlepony.unicopia.server.world.Ether;
|
||||||
|
@ -23,15 +21,18 @@ import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class PlacementControlSpell extends AbstractDelegatingSpell implements OrientedSpell {
|
public class PlacementControlSpell extends AbstractSpell implements OrientedSpell {
|
||||||
@Nullable
|
@Nullable
|
||||||
private UUID placedSpellId;
|
private UUID placedSpellId;
|
||||||
private final EntityReference<CastSpellEntity> castEntity = new EntityReference<>();
|
@Nullable
|
||||||
|
private UUID placedEntityId;
|
||||||
|
|
||||||
private Optional<RegistryKey<World>> dimension = Optional.empty();
|
private Optional<RegistryKey<World>> dimension = Optional.empty();
|
||||||
private Optional<Vec3d> position = Optional.empty();
|
private Optional<Vec3d> position = Optional.empty();
|
||||||
private Optional<Vec3d> orientation = Optional.empty();
|
private Optional<Vec3d> orientation = Optional.empty();
|
||||||
|
|
||||||
|
private SpellReference<Spell> delegate = new SpellReference<>();
|
||||||
|
|
||||||
public PlacementControlSpell(CustomisedSpellType<?> type) {
|
public PlacementControlSpell(CustomisedSpellType<?> type) {
|
||||||
super(type);
|
super(type);
|
||||||
}
|
}
|
||||||
|
@ -41,6 +42,11 @@ public class PlacementControlSpell extends AbstractDelegatingSpell implements Or
|
||||||
this.delegate.set(delegate);
|
this.delegate.set(delegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Spell getDelegate() {
|
||||||
|
return delegate.get();
|
||||||
|
}
|
||||||
|
|
||||||
public Optional<Vec3d> getPosition() {
|
public Optional<Vec3d> getPosition() {
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
@ -56,107 +62,91 @@ public class PlacementControlSpell extends AbstractDelegatingSpell implements Or
|
||||||
@Override
|
@Override
|
||||||
public void setOrientation(Caster<?> caster, float pitch, float yaw) {
|
public void setOrientation(Caster<?> caster, float pitch, float yaw) {
|
||||||
this.orientation = Optional.of(new Vec3d(pitch, yaw, 0));
|
this.orientation = Optional.of(new Vec3d(pitch, yaw, 0));
|
||||||
castEntity.ifPresent(caster.asWorld(), entity -> {
|
setDirty();
|
||||||
entity.getSpellSlot().stream(SpellPredicate.IS_ORIENTED).forEach(spell -> {
|
if (!caster.isClient() && placedEntityId != null) {
|
||||||
if (!getTypeAndTraits().type().test(spell)) {
|
getWorld(caster).ifPresent(world -> {
|
||||||
spell.setOrientation(caster, pitch, yaw);
|
var entry = Ether.get(world).get(SpellType.PLACED_SPELL, placedEntityId, placedSpellId);
|
||||||
|
if (entry != null) {
|
||||||
|
entry.setPitch(pitch);
|
||||||
|
entry.setYaw(yaw);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
setDirty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Caster<?> caster) {
|
public boolean apply(Caster<?> caster) {
|
||||||
boolean result = super.apply(caster);
|
boolean result = super.apply(caster);
|
||||||
if (result) {
|
if (result) {
|
||||||
if (!caster.isClient()) {
|
|
||||||
Ether.get(caster.asWorld()).getOrCreate(this, caster);
|
|
||||||
}
|
|
||||||
if (dimension.isEmpty()) {
|
if (dimension.isEmpty()) {
|
||||||
setDimension(caster.asWorld().getRegistryKey());
|
setDimension(caster.asWorld().getRegistryKey());
|
||||||
}
|
}
|
||||||
if (position.isEmpty()) {
|
if (position.isEmpty()) {
|
||||||
setPosition(caster.asEntity().getPos());
|
setPosition(caster.asEntity().getPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PlaceableSpell copy = new PlaceableSpell(caster, this, delegate.get());
|
||||||
|
|
||||||
|
Vec3d pos = position.orElse(caster.asEntity().getPos());
|
||||||
|
Vec3d rot = orientation.orElse(Vec3d.ZERO);
|
||||||
|
|
||||||
|
CastSpellEntity entity = UEntities.CAST_SPELL.create(caster.asWorld());
|
||||||
|
entity.setCaster(caster);
|
||||||
|
entity.updatePositionAndAngles(pos.x, pos.y, pos.z, (float)rot.y, (float)rot.x);
|
||||||
|
entity.setYaw((float)rot.y);
|
||||||
|
entity.setPitch((float)rot.x);
|
||||||
|
copy.apply(entity);
|
||||||
|
entity.getWorld().spawnEntity(entity);
|
||||||
|
|
||||||
|
placedSpellId = copy.getUuid();
|
||||||
|
placedEntityId = entity.getUuid();
|
||||||
|
setDirty();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tick(Caster<?> source, Situation situation) {
|
public boolean tick(Caster<?> source, Situation situation) {
|
||||||
if (!source.isClient()) {
|
if (!source.isClient() && !checkConnection(source)) {
|
||||||
Ether.get(source.asWorld()).getOrCreate(this, source);
|
setDead();
|
||||||
castEntity.getTarget().ifPresentOrElse(target -> {
|
|
||||||
if (!checkConnection(source, target)) {
|
|
||||||
setDead();
|
|
||||||
}
|
|
||||||
}, () -> spawnPlacedEntity(source));
|
|
||||||
}
|
}
|
||||||
return !isDead();
|
return !isDead();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void spawnPlacedEntity(Caster<?> source) {
|
private boolean checkConnection(Caster<?> source) {
|
||||||
PlaceableSpell copy = new PlaceableSpell(source, this, getDelegate());
|
return getWorld(source).map(world -> Ether.get(world).get(SpellType.PLACED_SPELL, placedEntityId, placedSpellId)).isPresent();
|
||||||
|
|
||||||
Vec3d pos = position.orElse(source.asEntity().getPos());
|
|
||||||
Vec3d rot = orientation.orElse(Vec3d.ZERO);
|
|
||||||
|
|
||||||
CastSpellEntity entity = UEntities.CAST_SPELL.create(source.asWorld());
|
|
||||||
entity.setCaster(source);
|
|
||||||
entity.updatePositionAndAngles(pos.x, pos.y, pos.z, (float)rot.y, (float)rot.x);
|
|
||||||
entity.setYaw((float)rot.y);
|
|
||||||
entity.setPitch((float)rot.x);
|
|
||||||
copy.apply(entity);
|
|
||||||
entity.getWorld().spawnEntity(entity);
|
|
||||||
|
|
||||||
placedSpellId = copy.getUuid();
|
|
||||||
castEntity.set(entity);
|
|
||||||
setDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkConnection(Caster<?> source, EntityValues<?> target) {
|
|
||||||
return getWorld(source)
|
|
||||||
.map(Ether::get)
|
|
||||||
.map(ether -> ether.get(SpellType.PLACED_SPELL, target, placedSpellId))
|
|
||||||
.isPresent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<World> getWorld(Caster<?> source) {
|
private Optional<World> getWorld(Caster<?> source) {
|
||||||
return dimension.map(source.asWorld().getServer()::getWorld);
|
return dimension.map(source.asWorld().getServer()::getWorld);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroyed(Caster<?> source) {
|
|
||||||
if (!source.isClient()) {
|
|
||||||
Ether.get(source.asWorld()).remove(this, source);
|
|
||||||
}
|
|
||||||
super.onDestroyed(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toNBT(NbtCompound compound) {
|
public void toNBT(NbtCompound compound) {
|
||||||
super.toNBT(compound);
|
super.toNBT(compound);
|
||||||
|
compound.put("spell", delegate.toNBT());
|
||||||
position.ifPresent(pos -> compound.put("position", NbtSerialisable.writeVector(pos)));
|
position.ifPresent(pos -> compound.put("position", NbtSerialisable.writeVector(pos)));
|
||||||
orientation.ifPresent(o -> compound.put("orientation", NbtSerialisable.writeVector(o)));
|
orientation.ifPresent(o -> compound.put("orientation", NbtSerialisable.writeVector(o)));
|
||||||
dimension.ifPresent(d -> compound.putString("dimension", d.getValue().toString()));
|
dimension.ifPresent(d -> compound.putString("dimension", d.getValue().toString()));
|
||||||
if (placedSpellId != null) {
|
if (placedSpellId != null) {
|
||||||
compound.putUuid("placedSpellId", placedSpellId);
|
compound.putUuid("placedSpellId", placedSpellId);
|
||||||
}
|
}
|
||||||
compound.put("castEntity", castEntity.toNBT());
|
if (placedEntityId != null) {
|
||||||
|
compound.putUuid("placedEntityId", placedEntityId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fromNBT(NbtCompound compound) {
|
public void fromNBT(NbtCompound compound) {
|
||||||
super.fromNBT(compound);
|
super.fromNBT(compound);
|
||||||
|
delegate.fromNBT(compound.getCompound("spell"));
|
||||||
placedSpellId = compound.containsUuid("placedSpellId") ? compound.getUuid("placedSpellId") : null;
|
placedSpellId = compound.containsUuid("placedSpellId") ? compound.getUuid("placedSpellId") : null;
|
||||||
|
placedEntityId = compound.containsUuid("placedEntityId") ? compound.getUuid("placedEntityId") : null;
|
||||||
position = compound.contains("position") ? Optional.of(NbtSerialisable.readVector(compound.getList("position", NbtElement.FLOAT_TYPE))) : Optional.empty();
|
position = compound.contains("position") ? Optional.of(NbtSerialisable.readVector(compound.getList("position", NbtElement.FLOAT_TYPE))) : Optional.empty();
|
||||||
orientation = compound.contains("orientation") ? Optional.of(NbtSerialisable.readVector(compound.getList("orientation", NbtElement.FLOAT_TYPE))) : Optional.empty();
|
orientation = compound.contains("orientation") ? Optional.of(NbtSerialisable.readVector(compound.getList("orientation", NbtElement.FLOAT_TYPE))) : Optional.empty();
|
||||||
if (compound.contains("dimension", NbtElement.STRING_TYPE)) {
|
if (compound.contains("dimension", NbtElement.STRING_TYPE)) {
|
||||||
dimension = Optional.ofNullable(Identifier.tryParse(compound.getString("dimension"))).map(id -> RegistryKey.of(RegistryKeys.WORLD, id));
|
dimension = Optional.ofNullable(Identifier.tryParse(compound.getString("dimension"))).map(id -> RegistryKey.of(RegistryKeys.WORLD, id));
|
||||||
}
|
}
|
||||||
castEntity.fromNBT(compound.getCompound("castEntity"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface PlacementDelegate {
|
public interface PlacementDelegate {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||||
|
import com.minelittlepony.unicopia.server.world.Ether;
|
||||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||||
|
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
@ -81,6 +82,9 @@ public interface Spell extends NbtSerialisable, Affine {
|
||||||
*/
|
*/
|
||||||
default boolean apply(Caster<?> caster) {
|
default boolean apply(Caster<?> caster) {
|
||||||
caster.getSpellSlot().put(this);
|
caster.getSpellSlot().put(this);
|
||||||
|
if (!caster.isClient()) {
|
||||||
|
Ether.get(caster.asWorld()).getOrCreate(this, caster);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import java.util.UUID;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||||
|
import com.minelittlepony.unicopia.server.world.Ether;
|
||||||
|
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
|
||||||
|
@ -78,9 +79,6 @@ public abstract class AbstractSpell implements Spell {
|
||||||
this.hidden = hidden;
|
this.hidden = hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onDestroyed(Caster<?> caster) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tickDying(Caster<?> caster) {
|
public void tickDying(Caster<?> caster) {
|
||||||
dead = true;
|
dead = true;
|
||||||
|
@ -96,6 +94,12 @@ public abstract class AbstractSpell implements Spell {
|
||||||
onDestroyed(caster);
|
onDestroyed(caster);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void onDestroyed(Caster<?> caster) {
|
||||||
|
if (!caster.isClient()) {
|
||||||
|
Ether.get(caster.asWorld()).remove(this, caster);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toNBT(NbtCompound compound) {
|
public void toNBT(NbtCompound compound) {
|
||||||
compound.putBoolean("dying", dying);
|
compound.putBoolean("dying", dying);
|
||||||
|
|
|
@ -54,11 +54,6 @@ public class AreaProtectionSpell extends AbstractAreaEffectSpell {
|
||||||
return !isDead();
|
return !isDead();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroyed(Caster<?> caster) {
|
|
||||||
Ether.get(caster.asWorld()).remove(this, caster);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the maximum radius of the shield. aka The area of effect.
|
* Calculates the maximum radius of the shield. aka The area of effect.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -139,6 +139,7 @@ public class BubbleSpell extends AbstractSpell implements TimedSpell,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroyed(Caster<?> source) {
|
protected void onDestroyed(Caster<?> source) {
|
||||||
|
super.onDestroyed(source);
|
||||||
if (source.asEntity() instanceof LivingEntity l) {
|
if (source.asEntity() instanceof LivingEntity l) {
|
||||||
MODIFIERS.forEach((attribute, modifier) -> {
|
MODIFIERS.forEach((attribute, modifier) -> {
|
||||||
if (l.getAttributes().hasAttribute(attribute)) {
|
if (l.getAttributes().hasAttribute(attribute)) {
|
||||||
|
|
|
@ -90,6 +90,7 @@ public class DisplacementSpell extends AbstractSpell implements HomingSpell, Pro
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroyed(Caster<?> caster) {
|
protected void onDestroyed(Caster<?> caster) {
|
||||||
|
super.onDestroyed(caster);
|
||||||
caster.getOriginatingCaster().asEntity().setGlowing(false);
|
caster.getOriginatingCaster().asEntity().setGlowing(false);
|
||||||
target.ifPresent(caster.asWorld(), e -> e.setGlowing(false));
|
target.ifPresent(caster.asWorld(), e -> e.setGlowing(false));
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,8 +92,7 @@ public class HydrophobicSpell extends AbstractSpell {
|
||||||
}
|
}
|
||||||
|
|
||||||
double range = getRange(source);
|
double range = getRange(source);
|
||||||
var entry = Ether.get(source.asWorld()).getOrCreate(this, source);
|
Ether.get(source.asWorld()).getOrCreate(this, source).setRadius((float)range);
|
||||||
entry.radius = (float)range;
|
|
||||||
|
|
||||||
source.spawnParticles(new Sphere(true, range), 10, pos -> {
|
source.spawnParticles(new Sphere(true, range), 10, pos -> {
|
||||||
BlockPos bp = BlockPos.ofFloored(pos);
|
BlockPos bp = BlockPos.ofFloored(pos);
|
||||||
|
@ -116,7 +115,7 @@ public class HydrophobicSpell extends AbstractSpell {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroyed(Caster<?> caster) {
|
protected void onDestroyed(Caster<?> caster) {
|
||||||
Ether.get(caster.asWorld()).remove(this, caster);
|
super.onDestroyed(caster);
|
||||||
storedFluidPositions.removeIf(entry -> {
|
storedFluidPositions.removeIf(entry -> {
|
||||||
if (caster.canModifyAt(entry.pos())) {
|
if (caster.canModifyAt(entry.pos())) {
|
||||||
entry.restore(caster.asWorld());
|
entry.restore(caster.asWorld());
|
||||||
|
@ -175,7 +174,7 @@ public class HydrophobicSpell extends AbstractSpell {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean blocksFlow(Ether.Entry<?> entry, Vec3d center, BlockPos pos, FluidState fluid) {
|
public boolean blocksFlow(Ether.Entry<?> entry, Vec3d center, BlockPos pos, FluidState fluid) {
|
||||||
return fluid.isIn(affectedFluid) && pos.isWithinDistance(center, (double)entry.radius + 1);
|
return fluid.isIn(affectedFluid) && pos.isWithinDistance(center, (double)entry.getRadius() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean blocksFluidFlow(BlockView world, BlockPos pos, FluidState state) {
|
public static boolean blocksFluidFlow(BlockView world, BlockPos pos, FluidState state) {
|
||||||
|
|
|
@ -91,6 +91,7 @@ public class LightSpell extends AbstractSpell implements TimedSpell, ProjectileD
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroyed(Caster<?> caster) {
|
protected void onDestroyed(Caster<?> caster) {
|
||||||
|
super.onDestroyed(caster);
|
||||||
if (caster.isClient()) {
|
if (caster.isClient()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,6 +153,7 @@ public class NecromancySpell extends AbstractAreaEffectSpell implements Projecti
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroyed(Caster<?> caster) {
|
protected void onDestroyed(Caster<?> caster) {
|
||||||
|
super.onDestroyed(caster);
|
||||||
if (caster.isClient()) {
|
if (caster.isClient()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,11 +121,9 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell.
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ether ether = Ether.get(source.asWorld());
|
var entry = Ether.get(source.asWorld()).getOrCreate(this, source);
|
||||||
var entry = ether.getOrCreate(this, source);
|
entry.setPitch(pitch);
|
||||||
entry.pitch = pitch;
|
entry.setYaw(yaw);
|
||||||
entry.yaw = yaw;
|
|
||||||
ether.markDirty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return !isDead();
|
return !isDead();
|
||||||
|
@ -133,13 +131,9 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell.
|
||||||
|
|
||||||
private void tickWithTargetLink(Caster<?> source, Ether.Entry<?> destination) {
|
private void tickWithTargetLink(Caster<?> source, Ether.Entry<?> destination) {
|
||||||
|
|
||||||
if (!MathHelper.approximatelyEquals(targetPortalPitch, destination.pitch)) {
|
if (destination.hasChanged()) {
|
||||||
targetPortalPitch = destination.pitch;
|
targetPortalPitch = destination.getPitch();
|
||||||
setDirty();
|
targetPortalYaw = destination.getYaw();
|
||||||
}
|
|
||||||
if (!MathHelper.approximatelyEquals(targetPortalYaw, destination.yaw)) {
|
|
||||||
targetPortalYaw = destination.yaw;
|
|
||||||
setDirty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destination.entity.getTarget().ifPresent(target -> {
|
destination.entity.getTarget().ifPresent(target -> {
|
||||||
|
@ -221,8 +215,10 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell.
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroyed(Caster<?> caster) {
|
protected void onDestroyed(Caster<?> caster) {
|
||||||
Ether.get(caster.asWorld()).remove(getType(), caster);
|
super.onDestroyed(caster);
|
||||||
getDestination(caster).ifPresent(Ether.Entry::release);
|
if (!caster.isClient()) {
|
||||||
|
getDestination(caster).ifPresent(Ether.Entry::release);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@ import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect;
|
||||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||||
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
||||||
|
import com.minelittlepony.unicopia.server.world.Ether;
|
||||||
import com.minelittlepony.unicopia.util.ColorHelper;
|
import com.minelittlepony.unicopia.util.ColorHelper;
|
||||||
import com.minelittlepony.unicopia.util.Lerp;
|
import com.minelittlepony.unicopia.util.Lerp;
|
||||||
import com.minelittlepony.unicopia.util.shape.Sphere;
|
import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||||
|
@ -115,6 +116,8 @@ public class ShieldSpell extends AbstractSpell {
|
||||||
|
|
||||||
if (source.isClient()) {
|
if (source.isClient()) {
|
||||||
generateParticles(source);
|
generateParticles(source);
|
||||||
|
} else {
|
||||||
|
Ether.get(source.asWorld()).getOrCreate(this, source).setRadius(radius.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (situation == Situation.PROJECTILE) {
|
if (situation == Situation.PROJECTILE) {
|
||||||
|
|
|
@ -136,7 +136,9 @@ public class DismissSpellScreen extends GameGui {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Spell getActualSpell() {
|
private Spell getActualSpell() {
|
||||||
return spell instanceof AbstractDelegatingSpell s && s.getDelegate() instanceof Spell p ? p : spell;
|
return spell instanceof AbstractDelegatingSpell s && s.getDelegate() instanceof Spell p ? p
|
||||||
|
: spell instanceof PlacementControlSpell s && s.getDelegate() instanceof Spell p ? p
|
||||||
|
: spell;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -161,11 +163,10 @@ public class DismissSpellScreen extends GameGui {
|
||||||
MatrixStack matrices = context.getMatrices();
|
MatrixStack matrices = context.getMatrices();
|
||||||
|
|
||||||
var type = actualSpell.getTypeAndTraits();
|
var type = actualSpell.getTypeAndTraits();
|
||||||
var affinity = actualSpell.getAffinity();
|
|
||||||
|
|
||||||
copy.set(mouseX - width * 0.5F - x * 0.5F, mouseY - height * 0.5F - y * 0.5F, 0, 0);
|
copy.set(mouseX - width * 0.5F - x * 0.5F, mouseY - height * 0.5F - y * 0.5F, 0, 0);
|
||||||
|
|
||||||
DrawableUtil.drawLine(matrices, 0, 0, (int)x, (int)y, affinity.getColor().getColorValue());
|
DrawableUtil.drawLine(matrices, 0, 0, (int)x, (int)y, actualSpell.getAffinity().getColor().getColorValue());
|
||||||
DrawableUtil.renderItemIcon(context, actualSpell.isDead() ? UItems.BOTCHED_GEM.getDefaultStack() : type.getDefaultStack(),
|
DrawableUtil.renderItemIcon(context, actualSpell.isDead() ? UItems.BOTCHED_GEM.getDefaultStack() : type.getDefaultStack(),
|
||||||
x - 8 - copy.x * 0.2F,
|
x - 8 - copy.x * 0.2F,
|
||||||
y - 8 - copy.y * 0.2F,
|
y - 8 - copy.y * 0.2F,
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.server.world;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.function.BiPredicate;
|
import java.util.function.BiPredicate;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
@ -15,6 +16,7 @@ import com.minelittlepony.unicopia.entity.EntityReference;
|
||||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||||
import net.minecraft.nbt.*;
|
import net.minecraft.nbt.*;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.world.PersistentState;
|
import net.minecraft.world.PersistentState;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
@ -168,9 +170,10 @@ public class Ether extends PersistentState {
|
||||||
private boolean removed;
|
private boolean removed;
|
||||||
private boolean taken;
|
private boolean taken;
|
||||||
|
|
||||||
public float pitch;
|
private float pitch;
|
||||||
public float yaw;
|
private final AtomicBoolean changed = new AtomicBoolean(true);
|
||||||
public float radius;
|
private float yaw;
|
||||||
|
private float radius;
|
||||||
|
|
||||||
private Entry(NbtElement nbt) {
|
private Entry(NbtElement nbt) {
|
||||||
this.entity = new EntityReference<>();
|
this.entity = new EntityReference<>();
|
||||||
|
@ -184,6 +187,46 @@ public class Ether extends PersistentState {
|
||||||
spellId = spell.getUuid();
|
spellId = spell.getUuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasChanged() {
|
||||||
|
return changed.getAndSet(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getPitch() {
|
||||||
|
return pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPitch(float pitch) {
|
||||||
|
if (!MathHelper.approximatelyEquals(this.pitch, pitch)) {
|
||||||
|
this.pitch = pitch;
|
||||||
|
changed.set(true);
|
||||||
|
}
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getYaw() {
|
||||||
|
return yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYaw(float yaw) {
|
||||||
|
if (!MathHelper.approximatelyEquals(this.yaw, yaw)) {
|
||||||
|
this.yaw = yaw;
|
||||||
|
changed.set(true);
|
||||||
|
}
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getRadius() {
|
||||||
|
return radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRadius(float radius) {
|
||||||
|
if (!MathHelper.approximatelyEquals(this.radius, radius)) {
|
||||||
|
this.radius = radius;
|
||||||
|
changed.set(true);
|
||||||
|
}
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
|
||||||
boolean isAlive() {
|
boolean isAlive() {
|
||||||
return !isDead();
|
return !isDead();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue