Skip to content

Commit

Permalink
Improve spell lookup performance by using the Ether
Browse files Browse the repository at this point in the history
  • Loading branch information
Sollace committed Jan 20, 2024
1 parent d22dd3b commit ab3ac8c
Show file tree
Hide file tree
Showing 12 changed files with 256 additions and 191 deletions.
12 changes: 0 additions & 12 deletions src/main/java/com/minelittlepony/unicopia/InteractionManager.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
package com.minelittlepony.unicopia;

import java.util.Map;
import java.util.Optional;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import com.minelittlepony.unicopia.ability.magic.CasterView;
import com.minelittlepony.unicopia.entity.player.dummy.DummyPlayerEntity;
import com.minelittlepony.unicopia.server.world.Ether;
import com.mojang.authlib.GameProfile;

import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;

public class InteractionManager {
Expand All @@ -37,13 +32,6 @@ public static InteractionManager instance() {
return INSTANCE;
}

public Optional<CasterView> getCasterView(BlockView view) {
if (view instanceof ServerWorld world) {
return Optional.of(Ether.get(world));
}
return Optional.empty();
}

public Map<Identifier, ?> readChapters(PacketByteBuf buf) {
throw new RuntimeException("Method not supported");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.minelittlepony.unicopia.entity.*;
import com.minelittlepony.unicopia.entity.damage.UDamageSources;
import com.minelittlepony.unicopia.particle.ParticleSource;
import com.minelittlepony.unicopia.server.world.Ether;
import com.minelittlepony.unicopia.server.world.ModificationType;
import com.minelittlepony.unicopia.util.SoundEmitter;
import com.minelittlepony.unicopia.util.VecHelper;
Expand Down Expand Up @@ -99,11 +100,7 @@ default boolean canCast() {
}

default boolean canCastAt(Vec3d pos) {
return findAllSpellsInRange(500, SpellType.ARCANE_PROTECTION::isOn).noneMatch(caster -> caster
.getSpellSlot().get(SpellType.ARCANE_PROTECTION, false)
.filter(spell -> spell.blocksMagicFor(caster, this, pos))
.isPresent()
);
return !Ether.get(asWorld()).anyMatch(SpellType.ARCANE_PROTECTION, (spell, caster) -> spell.blocksMagicFor(caster, this, pos));
}

static Stream<Caster<?>> stream(Stream<Entity> entities) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ public class PlaceableSpell extends AbstractDelegatingSpell implements OrientedS
*/
private final ParticleHandle particlEffect = new ParticleHandle();

/**
* ID of the placed counterpart of this spell.
*/
@Nullable
private UUID placedSpellId;

/**
* The cast spell entity
*/
Expand Down Expand Up @@ -82,10 +88,8 @@ public void setDead() {

@Override
public boolean tick(Caster<?> source, Situation situation) {

if (situation == Situation.BODY) {
if (!source.isClient()) {

if (dimension == null) {
dimension = source.asWorld().getRegistryKey();
if (source instanceof Pony) {
Expand All @@ -105,8 +109,7 @@ public boolean tick(Caster<?> source, Situation situation) {

if (situation == Situation.GROUND_ENTITY) {
if (!source.isClient()) {
Ether ether = Ether.get(source.asWorld());
if (ether.getEntry(getType(), source).isEmpty()) {
if (Ether.get(source.asWorld()).get(this, source) == null) {
setDead();
return false;
}
Expand All @@ -127,7 +130,7 @@ public boolean tick(Caster<?> source, Situation situation) {
}

private void checkDetachment(Caster<?> source, EntityValues<?> target) {
if (getWorld(source).map(Ether::get).flatMap(ether -> ether.getEntry(getType(), target.uuid())).isEmpty()) {
if (getWorld(source).map(Ether::get).map(ether -> ether.get(getType(), target, placedSpellId)).isEmpty()) {
setDead();
}
}
Expand All @@ -143,7 +146,8 @@ private void spawnPlacedEntity(Caster<?> source) {
entity.getSpellSlot().put(copy);
entity.setCaster(source);
entity.getWorld().spawnEntity(entity);
Ether.get(entity.getWorld()).put(getType(), entity);
placedSpellId = copy.getUuid();
Ether.get(entity.getWorld()).getOrCreate(copy, entity);

castEntity.set(entity);
setDirty();
Expand Down Expand Up @@ -174,16 +178,15 @@ protected void onDestroyed(Caster<?> source) {
if (!source.isClient()) {
castEntity.getTarget().ifPresent(target -> {
getWorld(source).map(Ether::get)
.flatMap(ether -> ether.getEntry(getType(), target.uuid()))
.ifPresent(Ether.Entry::markDead);
.ifPresent(ether -> ether.remove(getType(), target.uuid()));
});
castEntity.set(null);
getSpellEntity(source).ifPresent(e -> {
castEntity.set(null);
});

if (source.asEntity() instanceof CastSpellEntity spellcast) {
Ether.get(source.asWorld()).remove(getType(), source);
Ether.get(source.asWorld()).remove(this, source);
}
}
super.onDestroyed(source);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
import com.minelittlepony.unicopia.server.world.Ether;
import com.minelittlepony.unicopia.util.shape.Sphere;

import net.minecraft.entity.Entity;
Expand Down Expand Up @@ -42,6 +43,8 @@ public boolean tick(Caster<?> source, Situation situation) {
source.addParticle(new MagicParticleEffect(getType().getColor()), pos, Vec3d.ZERO);
}
});
} else {
Ether.get(source.asWorld()).getOrCreate(this, source);
}

source.findAllSpellsInRange(radius, e -> isValidTarget(source, e)).filter(caster -> !caster.hasCommonOwner(source)).forEach(caster -> {
Expand All @@ -51,6 +54,11 @@ public boolean tick(Caster<?> source, Situation situation) {
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.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import net.minecraft.util.math.Vec3d;

/**
* An area-effect spell that disperses illussions.
* An area-effect spell that disperses illusions.
*/
public class DisperseIllusionSpell extends AbstractAreaEffectSpell {
protected DisperseIllusionSpell(CustomisedSpellType<?> type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@

import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.CasterView;
import com.minelittlepony.unicopia.ability.magic.spell.CastingMethod;
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
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.Trait;
import com.minelittlepony.unicopia.advancement.UCriteria;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.particle.UParticles;
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
import com.minelittlepony.unicopia.server.world.Ether;
import com.minelittlepony.unicopia.util.NbtSerialisable;
import com.minelittlepony.unicopia.util.shape.*;

Expand All @@ -21,8 +23,10 @@
import net.minecraft.nbt.*;
import net.minecraft.state.property.Properties;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;

public class HydrophobicSpell extends AbstractSpell {
Expand All @@ -41,16 +45,15 @@ protected HydrophobicSpell(CustomisedSpellType<?> type, TagKey<Fluid> affectedFl
}

@Override
public boolean apply(Caster<?> source) {
if (getTraits().get(Trait.GENEROSITY) > 0) {
return toPlaceable().apply(source);
public Spell prepareForCast(Caster<?> caster, CastingMethod method) {
if ((method == CastingMethod.DIRECT || method == CastingMethod.STAFF) && getTraits().get(Trait.GENEROSITY) > 0) {
return toPlaceable();
}
return super.apply(source);
return this;
}

@Override
public boolean tick(Caster<?> source, Situation situation) {

if (!source.isClient()) {
World world = source.asWorld();

Expand Down Expand Up @@ -86,7 +89,11 @@ public boolean tick(Caster<?> source, Situation situation) {
setDead();
}

source.spawnParticles(new Sphere(true, getRange(source)), 10, pos -> {
double range = getRange(source);
var entry = Ether.get(source.asWorld()).getOrCreate(this, source);
entry.radius = (float)range;

source.spawnParticles(new Sphere(true, range), 10, pos -> {
BlockPos bp = BlockPos.ofFloored(pos);
if (source.asWorld().getFluidState(bp.up()).isIn(affectedFluid)) {
source.addParticle(UParticles.RAIN_DROPS, pos, Vec3d.ZERO);
Expand All @@ -107,6 +114,7 @@ public boolean tick(Caster<?> source, Situation situation) {

@Override
protected void onDestroyed(Caster<?> caster) {
Ether.get(caster.asWorld()).remove(this, caster);
storedFluidPositions.removeIf(entry -> {
entry.restore(caster.asWorld());
return true;
Expand Down Expand Up @@ -162,13 +170,20 @@ void restore(World world) {
}
}

public boolean blocksFlow(Caster<?> caster, BlockPos pos, FluidState fluid) {
return fluid.isIn(affectedFluid) && pos.isWithinDistance(caster.getOrigin(), getRange(caster) + 1);
public boolean blocksFlow(Ether.Entry<?> entry, Vec3d center, BlockPos pos, FluidState fluid) {
return fluid.isIn(affectedFluid) && pos.isWithinDistance(center, (double)entry.radius + 1);
}

public static boolean blocksFluidFlow(CasterView world, BlockPos pos, FluidState state) {
return world.findAllSpellsInRange(pos, 500, SpellType.HYDROPHOBIC).anyMatch(pair -> {
return pair.getValue().blocksFlow(pair.getKey(), pos, state);
});
public static boolean blocksFluidFlow(BlockView world, BlockPos pos, FluidState state) {
if (world instanceof ServerWorld sw) {
return Ether.get(sw).anyMatch(SpellType.HYDROPHOBIC, entry -> {
var spell = entry.getSpell();
var target = entry.entity.getTarget().orElse(null);
return spell != null && target != null && spell.blocksFlow(entry, target.pos(), pos, state);
});
}

return false;

}
}
Loading

0 comments on commit ab3ac8c

Please sign in to comment.