Fixed light sources not being removed after light-emitting entities are removed

This commit is contained in:
Sollace 2022-01-01 19:14:37 +02:00
parent 63f70faab1
commit e3d1f8c973
4 changed files with 86 additions and 54 deletions

View file

@ -25,7 +25,7 @@ import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.world.World;
public class CastSpellEntity extends Entity implements Caster<LivingEntity>, LightEmittingEntity {
public class CastSpellEntity extends LightEmittingEntity implements Caster<LivingEntity> {
private static final TrackedData<Float> GRAVITY = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.FLOAT);
private static final TrackedData<Optional<UUID>> SPELL = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.OPTIONAL_UUID);
@ -54,7 +54,6 @@ public class CastSpellEntity extends Entity implements Caster<LivingEntity>, Lig
};
private final EntityReference<LivingEntity> owner = new EntityReference<>();
private final LightEmitter<?> emitter = new LightEmitter<>(this);
private int orphanedTicks;
@ -101,8 +100,6 @@ public class CastSpellEntity extends Entity implements Caster<LivingEntity>, Lig
orphanedTicks = 0;
emitter.tick();
if (dataTracker.get(SPELL).filter(spellId -> {
return getSpellSlot().forEach(spell -> {
return spell.getUuid().equals(spellId) ? Operation.ofBoolean(spell.tick(this, Situation.GROUND_ENTITY)) : Operation.SKIP;

View file

@ -0,0 +1,57 @@
package com.minelittlepony.unicopia.entity;
import org.jetbrains.annotations.Nullable;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
public interface DynamicLightSource {
int getLightLevel();
static final class LightEmitter<T extends Entity & DynamicLightSource> {
@Nullable
private BlockPos lastPos;
private final T entity;
LightEmitter(T entity) {
this.entity = entity;
}
@SuppressWarnings("deprecation")
void tick() {
if (entity.world.isClient) {
if (entity.isRemoved()) {
remove();
return;
}
int light = entity.getLightLevel();
if (light <= 0) {
return;
}
BlockPos currentPos = entity.getBlockPos();
if (!currentPos.equals(lastPos) && entity.world.isChunkLoaded(currentPos)) {
try {
if (lastPos != null) {
entity.world.getLightingProvider().checkBlock(lastPos);
}
entity.world.getLightingProvider().addLightSource(currentPos, light);
lastPos = currentPos;
} catch (Exception ignored) { }
}
}
}
void remove() {
if (entity.world.isClient && lastPos != null) {
try {
entity.world.getLightingProvider().checkBlock(lastPos);
} catch (Exception ignored) {}
}
}
}
}

View file

@ -42,7 +42,7 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraft.world.event.GameEvent;
public class FairyEntity extends PathAwareEntity implements LightEmittingEntity, Owned<LivingEntity> {
public class FairyEntity extends PathAwareEntity implements DynamicLightSource, Owned<LivingEntity> {
private final EntityReference<LivingEntity> owner = new EntityReference<>();
private final EntityReference<LivingEntity> assignment = new EntityReference<>();
@ -215,6 +215,12 @@ public class FairyEntity extends PathAwareEntity implements LightEmittingEntity,
return false;
}
@Override
public void setRemoved(RemovalReason reason) {
super.setRemoved(reason);
emitter.remove();
}
@Override
public void onRemoved() {
super.onRemoved();

View file

@ -1,59 +1,31 @@
package com.minelittlepony.unicopia.entity;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.entity.EntityType;
import net.minecraft.world.World;
public interface LightEmittingEntity {
public abstract class LightEmittingEntity extends Entity implements DynamicLightSource {
private final LightEmitter<?> emitter = new LightEmitter<>(this);
int getLightLevel();
static class LightEmitter<T extends Entity & LightEmittingEntity> {
private BlockPos lastPos;
private final T entity;
public LightEmitter(T entity) {
this.entity = entity;
public LightEmittingEntity(EntityType<?> type, World world) {
super(type, world);
}
@SuppressWarnings("deprecation")
@Override
public void tick() {
if (entity.isRemoved()) {
remove();
return;
super.tick();
emitter.tick();
}
if (entity.world.isClient) {
int light = entity.getLightLevel();
if (light <= 0) {
return;
@Override
public void setRemoved(RemovalReason reason) {
super.setRemoved(reason);
emitter.remove();
}
BlockPos currentPos = entity.getBlockPos();
if (entity.world.isChunkLoaded(currentPos)) {
try {
if (lastPos != null && !currentPos.equals(lastPos)) {
entity.world.getLightingProvider().checkBlock(lastPos);
}
entity.world.getLightingProvider().addLightSource(currentPos, light);
} catch (Exception ignored) {
}
lastPos = currentPos;
}
}
}
void remove() {
if (entity.world.isClient) {
try {
entity.world.getLightingProvider().checkBlock(entity.getBlockPos());
} catch (Exception ignored) {}
}
}
@Override
public void onRemoved() {
super.onRemoved();
emitter.remove();
}
}