mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
More refinements to portal spells
This commit is contained in:
parent
b83f947488
commit
88e078cfc7
3 changed files with 87 additions and 16 deletions
|
@ -91,6 +91,13 @@ public class PlaceableSpell extends AbstractDelegatingSpell {
|
||||||
|
|
||||||
castEntity.set(entity);
|
castEntity.set(entity);
|
||||||
setDirty();
|
setDirty();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (getWorld(source).map(Ether::get)
|
||||||
|
.flatMap(ether -> castEntity.getId().flatMap(id -> ether.getEntry(getType(), id)))
|
||||||
|
.isEmpty()) {
|
||||||
|
setDead();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,9 +107,7 @@ public class PlaceableSpell extends AbstractDelegatingSpell {
|
||||||
if (situation == Situation.GROUND_ENTITY) {
|
if (situation == Situation.GROUND_ENTITY) {
|
||||||
|
|
||||||
if (!source.isClient()) {
|
if (!source.isClient()) {
|
||||||
Ether ether = Ether.get(source.getReferenceWorld());
|
if (Ether.get(source.getReferenceWorld()).getEntry(getType(), source).isEmpty()) {
|
||||||
if (ether.getEntry(getType(), source).filter(Ether.Entry::isAlive).isEmpty()) {
|
|
||||||
ether.remove(getType(), source);
|
|
||||||
setDead();
|
setDead();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -128,6 +133,7 @@ public class PlaceableSpell extends AbstractDelegatingSpell {
|
||||||
.flatMap(ether -> ether.getEntry(getType(), id))
|
.flatMap(ether -> ether.getEntry(getType(), id))
|
||||||
.ifPresent(Ether.Entry::markDead);
|
.ifPresent(Ether.Entry::markDead);
|
||||||
});
|
});
|
||||||
|
castEntity.set(null);
|
||||||
getSpellEntity(source).ifPresent(e -> {
|
getSpellEntity(source).ifPresent(e -> {
|
||||||
castEntity.set(null);
|
castEntity.set(null);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,25 +1,33 @@
|
||||||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.USounds;
|
import com.minelittlepony.unicopia.USounds;
|
||||||
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||||
import com.minelittlepony.unicopia.block.data.Ether;
|
import com.minelittlepony.unicopia.block.data.Ether;
|
||||||
import com.minelittlepony.unicopia.entity.CastSpellEntity;
|
import com.minelittlepony.unicopia.entity.CastSpellEntity;
|
||||||
import com.minelittlepony.unicopia.entity.EntityReference;
|
import com.minelittlepony.unicopia.entity.EntityReference;
|
||||||
import com.minelittlepony.unicopia.particle.*;
|
import com.minelittlepony.unicopia.particle.*;
|
||||||
import com.minelittlepony.unicopia.particle.ParticleHandle.Attachment;
|
|
||||||
import com.minelittlepony.unicopia.util.shape.Sphere;
|
import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
import net.minecraft.particle.ParticleEffect;
|
||||||
|
import net.minecraft.particle.ParticleTypes;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.WorldEvents;
|
||||||
|
|
||||||
public class PortalSpell extends AbstractSpell {
|
public class PortalSpell extends AbstractSpell {
|
||||||
|
public static final int MAX_COOLDOWN = 20;
|
||||||
private final EntityReference<CastSpellEntity> teleportationTarget = new EntityReference<>();
|
private final EntityReference<CastSpellEntity> teleportationTarget = new EntityReference<>();
|
||||||
|
|
||||||
private boolean publishedPosition;
|
private boolean publishedPosition;
|
||||||
|
|
||||||
private final ParticleHandle particlEffect = new ParticleHandle();
|
private final ParticleHandle particlEffect = new ParticleHandle();
|
||||||
|
|
||||||
|
private int cooldown = MAX_COOLDOWN;
|
||||||
|
|
||||||
protected PortalSpell(CustomisedSpellType<?> type) {
|
protected PortalSpell(CustomisedSpellType<?> type) {
|
||||||
super(type);
|
super(type);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +39,20 @@ public class PortalSpell extends AbstractSpell {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tick(Caster<?> source, Situation situation) {
|
public boolean tick(Caster<?> source, Situation situation) {
|
||||||
|
|
||||||
if (situation == Situation.GROUND) {
|
if (situation == Situation.GROUND) {
|
||||||
|
if (!source.isClient()) {
|
||||||
|
teleportationTarget.getId().ifPresent(id -> {
|
||||||
|
Ether ether = Ether.get(source.getReferenceWorld());
|
||||||
|
if (ether.getEntry(getType(), id).isEmpty()) {
|
||||||
|
Unicopia.LOGGER.debug("Lost sibling, breaking connection to " + id);
|
||||||
|
teleportationTarget.set(null);
|
||||||
|
setDirty();
|
||||||
|
source.getReferenceWorld().syncWorldEvent(WorldEvents.BLOCK_BROKEN, source.getOrigin(), Block.getRawIdFromState(Blocks.GLASS.getDefaultState()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
teleportationTarget.getPosition().ifPresentOrElse(
|
teleportationTarget.getPosition().ifPresentOrElse(
|
||||||
targetPos -> tickWithTargetLink(source, targetPos),
|
targetPos -> tickWithTargetLink(source, targetPos),
|
||||||
() -> findLink(source)
|
() -> findLink(source)
|
||||||
|
@ -42,11 +63,21 @@ public class PortalSpell extends AbstractSpell {
|
||||||
Ether.get(source.getReferenceWorld()).put(getType(), source);
|
Ether.get(source.getReferenceWorld()).put(getType(), source);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source.isClient()) {
|
if (source.isClient() && cooldown <= 0) {
|
||||||
Vec3d origin = source.getOriginVector();
|
Vec3d origin = source.getOriginVector();
|
||||||
|
|
||||||
source.spawnParticles(origin, new Sphere(true, 2, 1, 0, 1), 17, pos -> {
|
ParticleEffect effect = teleportationTarget.getPosition()
|
||||||
source.addParticle(new MagicParticleEffect(getType().getColor()), pos, Vec3d.ZERO);
|
.map(target -> {
|
||||||
|
getType();
|
||||||
|
return new FollowingParticleEffect(UParticles.HEALTH_DRAIN, target, 0.2F).withChild(ParticleTypes.ELECTRIC_SPARK);
|
||||||
|
})
|
||||||
|
.orElseGet(() -> {
|
||||||
|
new MagicParticleEffect(getType().getColor());
|
||||||
|
return ParticleTypes.ELECTRIC_SPARK;
|
||||||
|
});
|
||||||
|
|
||||||
|
source.spawnParticles(origin, new Sphere(true, 2, 1, 0, 1), 3, pos -> {
|
||||||
|
source.addParticle(effect, pos, Vec3d.ZERO);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,11 +87,15 @@ public class PortalSpell extends AbstractSpell {
|
||||||
|
|
||||||
private void tickWithTargetLink(Caster<?> source, Vec3d targetPos) {
|
private void tickWithTargetLink(Caster<?> source, Vec3d targetPos) {
|
||||||
particlEffect.update(getUuid(), source, spawner -> {
|
particlEffect.update(getUuid(), source, spawner -> {
|
||||||
spawner.addParticle(new SphereParticleEffect(UParticles.DISK, getType().getColor(), 0.9F, 2), source.getOriginVector(), Vec3d.ZERO);
|
spawner.addParticle(new SphereParticleEffect(UParticles.DISK, getType().getColor(), 0.8F, 2), source.getOriginVector(), Vec3d.ZERO);
|
||||||
}).ifPresent(p -> {
|
|
||||||
p.setAttribute(Attachment.ATTR_COLOR, getType().getColor());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (cooldown > 0) {
|
||||||
|
cooldown--;
|
||||||
|
setDirty();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Vec3d center = source.getOriginVector();
|
Vec3d center = source.getOriginVector();
|
||||||
source.findAllEntitiesInRange(1).filter(e -> true).forEach(entity -> {
|
source.findAllEntitiesInRange(1).filter(e -> true).forEach(entity -> {
|
||||||
if (!entity.hasPortalCooldown() && entity.timeUntilRegen <= 0) {
|
if (!entity.hasPortalCooldown() && entity.timeUntilRegen <= 0) {
|
||||||
|
@ -70,13 +105,21 @@ public class PortalSpell extends AbstractSpell {
|
||||||
|
|
||||||
entity.playSound(USounds.ENTITY_PLAYER_UNICORN_TELEPORT, 1, 1);
|
entity.playSound(USounds.ENTITY_PLAYER_UNICORN_TELEPORT, 1, 1);
|
||||||
entity.teleport(destination.x, destination.y, destination.z);
|
entity.teleport(destination.x, destination.y, destination.z);
|
||||||
|
entity.playSound(USounds.ENTITY_PLAYER_UNICORN_TELEPORT, 1, 1);
|
||||||
|
setDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
ParticleUtils.spawnParticles(new MagicParticleEffect(getType().getColor()), entity, 7);
|
ParticleUtils.spawnParticles(new MagicParticleEffect(getType().getColor()), entity, 7);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void findLink(Caster<?> source) {
|
private void findLink(Caster<?> source) {
|
||||||
|
|
||||||
|
if (source.isClient()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Ether ether = Ether.get(source.getReferenceWorld());
|
Ether ether = Ether.get(source.getReferenceWorld());
|
||||||
ether.getEntries(getType())
|
ether.getEntries(getType())
|
||||||
.stream()
|
.stream()
|
||||||
|
@ -85,12 +128,15 @@ public class PortalSpell extends AbstractSpell {
|
||||||
.ifPresent(entry -> {
|
.ifPresent(entry -> {
|
||||||
entry.setTaken(true);
|
entry.setTaken(true);
|
||||||
teleportationTarget.copyFrom((EntityReference<CastSpellEntity>)entry.entity);
|
teleportationTarget.copyFrom((EntityReference<CastSpellEntity>)entry.entity);
|
||||||
|
setDirty();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyed(Caster<?> caster) {
|
public void onDestroyed(Caster<?> caster) {
|
||||||
Ether.get(caster.getReferenceWorld()).remove(getType(), caster.getEntity().getUuid());
|
Ether ether = Ether.get(caster.getReferenceWorld());
|
||||||
|
ether.remove(getType(), caster.getEntity().getUuid());
|
||||||
|
teleportationTarget.getId().flatMap(id -> ether.getEntry(getType(), id)).ifPresent(e -> e.setTaken(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -98,6 +144,7 @@ public class PortalSpell extends AbstractSpell {
|
||||||
super.toNBT(compound);
|
super.toNBT(compound);
|
||||||
compound.putBoolean("publishedPosition", publishedPosition);
|
compound.putBoolean("publishedPosition", publishedPosition);
|
||||||
compound.put("teleportationTarget", teleportationTarget.toNBT());
|
compound.put("teleportationTarget", teleportationTarget.toNBT());
|
||||||
|
compound.putInt("cooldown", cooldown);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -105,6 +152,7 @@ public class PortalSpell extends AbstractSpell {
|
||||||
super.fromNBT(compound);
|
super.fromNBT(compound);
|
||||||
publishedPosition = compound.getBoolean("publishedPosition");
|
publishedPosition = compound.getBoolean("publishedPosition");
|
||||||
teleportationTarget.fromNBT(compound.getCompound("teleportationTarget"));
|
teleportationTarget.fromNBT(compound.getCompound("teleportationTarget"));
|
||||||
|
cooldown = compound.getInt("cooldown");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -49,7 +49,11 @@ public class Ether extends PersistentState {
|
||||||
synchronized (locker) {
|
synchronized (locker) {
|
||||||
advertisingEndpoints.forEach((id, uuids) -> {
|
advertisingEndpoints.forEach((id, uuids) -> {
|
||||||
NbtList list = new NbtList();
|
NbtList list = new NbtList();
|
||||||
uuids.forEach(uuid -> list.add(uuid.toNBT()));
|
uuids.forEach(uuid -> {
|
||||||
|
if (uuid.isAlive()) {
|
||||||
|
list.add(uuid.toNBT());
|
||||||
|
}
|
||||||
|
});
|
||||||
compound.put(id.toString(), list);
|
compound.put(id.toString(), list);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -69,7 +73,7 @@ public class Ether extends PersistentState {
|
||||||
Identifier typeId = spellType.getId();
|
Identifier typeId = spellType.getId();
|
||||||
Set<Entry> refs = advertisingEndpoints.get(typeId);
|
Set<Entry> refs = advertisingEndpoints.get(typeId);
|
||||||
if (refs != null) {
|
if (refs != null) {
|
||||||
refs.removeIf(ref -> ref.entity.getId().orElse(Util.NIL_UUID).equals(id));
|
refs.removeIf(ref -> ref.removed || ref.entity.getId().orElse(Util.NIL_UUID).equals(id));
|
||||||
if (refs.isEmpty()) {
|
if (refs.isEmpty()) {
|
||||||
advertisingEndpoints.remove(typeId);
|
advertisingEndpoints.remove(typeId);
|
||||||
}
|
}
|
||||||
|
@ -88,7 +92,14 @@ public class Ether extends PersistentState {
|
||||||
|
|
||||||
private Set<Entry> getEntries(Identifier typeId) {
|
private Set<Entry> getEntries(Identifier typeId) {
|
||||||
synchronized (locker) {
|
synchronized (locker) {
|
||||||
return advertisingEndpoints.computeIfAbsent(typeId, i -> new HashSet<>());
|
return advertisingEndpoints.compute(typeId, (k, old) -> {
|
||||||
|
if (old == null) {
|
||||||
|
old = new HashSet<>();
|
||||||
|
} else {
|
||||||
|
old.removeIf(Entry::isDead);
|
||||||
|
}
|
||||||
|
return old;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,11 +128,16 @@ public class Ether extends PersistentState {
|
||||||
entity = new EntityReference<>(caster.getEntity());
|
entity = new EntityReference<>(caster.getEntity());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAlive() {
|
boolean isAlive() {
|
||||||
return !removed;
|
return !removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isDead() {
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
public void markDead() {
|
public void markDead() {
|
||||||
|
Unicopia.LOGGER.debug("Marking " + entity.getId().orElse(null) + " as dead");
|
||||||
removed = true;
|
removed = true;
|
||||||
markDirty();
|
markDirty();
|
||||||
}
|
}
|
||||||
|
@ -138,9 +154,10 @@ public class Ether extends PersistentState {
|
||||||
@Override
|
@Override
|
||||||
public void toNBT(NbtCompound compound) {
|
public void toNBT(NbtCompound compound) {
|
||||||
entity.toNBT(compound);
|
entity.toNBT(compound);
|
||||||
compound.putBoolean("remove", removed);
|
compound.putBoolean("removed", removed);
|
||||||
compound.putBoolean("taken", taken);
|
compound.putBoolean("taken", taken);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fromNBT(NbtCompound compound) {
|
public void fromNBT(NbtCompound compound) {
|
||||||
entity.fromNBT(compound);
|
entity.fromNBT(compound);
|
||||||
|
|
Loading…
Reference in a new issue