Warden lives!

This commit is contained in:
ItsBlackGear 2022-07-22 21:50:52 -04:00
parent 6c66e8e946
commit 010140a36c
9 changed files with 162 additions and 31 deletions

View file

@ -4,7 +4,7 @@ import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.client.particle.ShriekParticleOptions;
import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents;
import com.cursedcauldron.wildbackport.common.blocks.SculkShriekerBlock;
import com.cursedcauldron.wildbackport.common.entities.warden.VibrationListenerSource;
import com.cursedcauldron.wildbackport.common.entities.warden.VibrationHandler;
import com.cursedcauldron.wildbackport.common.entities.Warden;
import com.cursedcauldron.wildbackport.common.entities.warden.WardenSpawnHelper;
import com.cursedcauldron.wildbackport.common.entities.warden.WardenSpawnTracker;
@ -41,7 +41,7 @@ import java.util.OptionalInt;
//<>
public class SculkShriekerBlockEntity extends BlockEntity implements VibrationListenerSource.VibrationConfig {
public class SculkShriekerBlockEntity extends BlockEntity implements VibrationHandler.VibrationConfig {
private static final Int2ObjectMap<SoundEvent> SOUND_BY_LEVEL = Util.make(new Int2ObjectOpenHashMap<>(), map -> {
map.put(1, WBSoundEvents.WARDEN_NEARBY_CLOSE);
map.put(2, WBSoundEvents.WARDEN_NEARBY_CLOSER);
@ -49,13 +49,13 @@ public class SculkShriekerBlockEntity extends BlockEntity implements VibrationLi
map.put(4, WBSoundEvents.WARDEN_LISTENING_ANGRY);
});
private int warningLevel;
private VibrationListenerSource listener = new VibrationListenerSource(new BlockPositionSource(this.worldPosition), 8, this, null, 0.0F, 0);
private VibrationHandler listener = new VibrationHandler(new BlockPositionSource(this.worldPosition), 8, this, null, 0.0F, 0);
public SculkShriekerBlockEntity(BlockPos pos, BlockState state) {
super(WBBlockEntities.SCULK_SHRIEKER.get(), pos, state);
}
public VibrationListenerSource getListener() {
public VibrationHandler getListener() {
return this.listener;
}
@ -67,7 +67,7 @@ public class SculkShriekerBlockEntity extends BlockEntity implements VibrationLi
}
if (tag.contains("listener", 10)) {
VibrationListenerSource.codec(this).parse(new Dynamic<>(NbtOps.INSTANCE, tag.getCompound("listener"))).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> this.listener = listener);
VibrationHandler.codec(this).parse(new Dynamic<>(NbtOps.INSTANCE, tag.getCompound("listener"))).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> this.listener = listener);
}
}
@ -75,7 +75,7 @@ public class SculkShriekerBlockEntity extends BlockEntity implements VibrationLi
protected void saveAdditional(CompoundTag tag) {
super.saveAdditional(tag);
tag.putInt("warning_level", this.warningLevel);
VibrationListenerSource.codec(this).encodeStart(NbtOps.INSTANCE, this.listener).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> tag.put("listener", listener));
VibrationHandler.codec(this).encodeStart(NbtOps.INSTANCE, this.listener).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> tag.put("listener", listener));
}
@Override
@ -160,7 +160,7 @@ public class SculkShriekerBlockEntity extends BlockEntity implements VibrationLi
this.playWardenReplySound();
}
Warden.addDarknessEffectToClosePlayers(level, Vec3.atCenterOf(this.getBlockPos()), null, 40);
Warden.addDarknessToClosePlayers(level, Vec3.atCenterOf(this.getBlockPos()), null, 40);
}
}

View file

@ -4,7 +4,7 @@ import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents;
import com.cursedcauldron.wildbackport.common.entities.brain.AllayBrain;
import com.cursedcauldron.wildbackport.common.entities.warden.MobPositionSource;
import com.cursedcauldron.wildbackport.common.entities.warden.VibrationListenerSource;
import com.cursedcauldron.wildbackport.common.entities.warden.VibrationHandler;
import com.cursedcauldron.wildbackport.common.registry.WBGameEvents;
import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules;
import com.cursedcauldron.wildbackport.common.tag.WBGameEventTags;
@ -64,12 +64,12 @@ import java.util.UUID;
//<>
public class Allay extends PathfinderMob implements InventoryCarrier, VibrationListenerSource.VibrationConfig {
public class Allay extends PathfinderMob implements InventoryCarrier, VibrationHandler.VibrationConfig {
protected static final ImmutableList<? extends SensorType<? extends Sensor<? super Allay>>> SENSORS = ImmutableList.of(SensorType.NEAREST_LIVING_ENTITIES, SensorType.NEAREST_PLAYERS, SensorType.HURT_BY, SensorType.NEAREST_ITEMS);
protected static final ImmutableList<MemoryModuleType<?>> MEMORIES = ImmutableList.of(MemoryModuleType.PATH, MemoryModuleType.LOOK_TARGET, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.HURT_BY, MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, WBMemoryModules.LIKED_PLAYER.get(), WBMemoryModules.LIKED_NOTEBLOCK.get(), WBMemoryModules.LIKED_NOTEBLOCK_COOLDOWN_TICKS.get(), WBMemoryModules.ITEM_PICKUP_COOLDOWN_TICKS.get());
public static final ImmutableList<Float> THROW_SOUND_PITCHES = ImmutableList.of(0.5625F, 0.625F, 0.75F, 0.9375F, 1.0F, 1.0F, 1.125F, 1.25F, 1.5F, 1.875F, 2.0F, 2.25F, 2.5F, 3.0F, 3.75F, 4.0F);
private final GameEventListenerRegistrar registrar;
private VibrationListenerSource listener;
private VibrationHandler listener;
private final SimpleContainer inventory = new SimpleContainer(1);
private float holdingTicks;
private float holdingTicksOld;
@ -78,7 +78,7 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationL
super(type, level);
this.moveControl = new FlyingMoveControl(this, 20, true);
this.setCanPickUpLoot(this.canPickUpLoot());
this.listener = new VibrationListenerSource(new MobPositionSource(this, this.getEyeHeight()), 16, this, null, 0.0F, 0);
this.listener = new VibrationHandler(new MobPositionSource(this, this.getEyeHeight()), 16, this, null, 0.0F, 0);
this.registrar = new GameEventListenerRegistrar(this.listener);
}
@ -355,14 +355,14 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationL
public void addAdditionalSaveData(CompoundTag tag) {
super.addAdditionalSaveData(tag);
tag.put("Inventory", this.inventory.createTag());
VibrationListenerSource.codec(this).encodeStart(NbtOps.INSTANCE, this.listener).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> tag.put("listener", listener));
VibrationHandler.codec(this).encodeStart(NbtOps.INSTANCE, this.listener).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> tag.put("listener", listener));
}
@Override
public void readAdditionalSaveData(CompoundTag tag) {
super.readAdditionalSaveData(tag);
this.inventory.fromTag(tag.getList("Inventory", 10));
if (tag.contains("listener", 10)) VibrationListenerSource.codec(this).parse(new Dynamic<>(NbtOps.INSTANCE, tag.getCompound("listener"))).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> this.listener = listener);
if (tag.contains("listener", 10)) VibrationHandler.codec(this).parse(new Dynamic<>(NbtOps.INSTANCE, tag.getCompound("listener"))).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> this.listener = listener);
}
public Iterable<BlockPos> getPotentialEscapePositions() {

View file

@ -8,7 +8,7 @@ import com.cursedcauldron.wildbackport.common.entities.brain.WardenBrain;
import com.cursedcauldron.wildbackport.common.entities.brain.warden.SonicBoom;
import com.cursedcauldron.wildbackport.common.entities.warden.Angriness;
import com.cursedcauldron.wildbackport.common.entities.warden.MobPositionSource;
import com.cursedcauldron.wildbackport.common.entities.warden.VibrationListenerSource;
import com.cursedcauldron.wildbackport.common.entities.warden.VibrationHandler;
import com.cursedcauldron.wildbackport.common.entities.warden.WardenAngerManager;
import com.cursedcauldron.wildbackport.common.registry.WBMobEffects;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities;
@ -68,8 +68,7 @@ import java.util.Random;
//<>
//TODO: fix warden not detecting vibrations by players
public class Warden extends Monster implements VibrationListenerSource.VibrationConfig {
public class Warden extends Monster implements VibrationHandler.VibrationConfig {
private static final EntityDataAccessor<Integer> ANGER = SynchedEntityData.defineId(Warden.class, EntityDataSerializers.INT);
private int tendrilPitchEnd;
private int tendrilPitchStart;
@ -82,12 +81,12 @@ public class Warden extends Monster implements VibrationListenerSource.Vibration
public AnimationState attackingAnimationState = new AnimationState();
public AnimationState sonicBoomAnimationState = new AnimationState();
private final GameEventListenerRegistrar gameEventHandler;
private VibrationListenerSource listener;
private final VibrationHandler listener;
private WardenAngerManager angerManager = new WardenAngerManager(this::isValidTarget, Collections.emptyList());
public Warden(EntityType<? extends Monster> type, Level level) {
super(type, level);
this.listener = new VibrationListenerSource(new MobPositionSource(this, this.getEyeHeight()), 16, this, null, 0.0F, 0);
this.listener = new VibrationHandler(new MobPositionSource(this, this.getEyeHeight()), 16, this);
this.gameEventHandler = new GameEventListenerRegistrar(this.listener);
this.xpReward = 5;
this.getNavigation().setCanFloat(true);
@ -205,7 +204,7 @@ public class Warden extends Monster implements VibrationListenerSource.Vibration
}
super.tick();
if (this.level.isClientSide) {
if (this.level.isClientSide()) {
if (this.tickCount % this.getHeartRate() == 0) {
this.heartPitchEnd = 10;
if (!this.isSilent()) {
@ -241,7 +240,7 @@ public class Warden extends Monster implements VibrationListenerSource.Vibration
this.level.getProfiler().pop();
super.customServerAiStep();
if ((this.tickCount + this.getId()) % 120 == 0) {
addDarknessEffectToClosePlayers(level, this.position(), this, 20);
addDarknessToClosePlayers(level, this.position(), this, 20);
}
if (this.tickCount % 20 == 0) {
@ -353,16 +352,16 @@ public class Warden extends Monster implements VibrationListenerSource.Vibration
return false;
}
public static void addDarknessEffectToClosePlayers(ServerLevel level, Vec3 pos, @Nullable Entity entity, int range) {
public static void addDarknessToClosePlayers(ServerLevel world, Vec3 pos, @Nullable Entity entity, int range) {
MobEffectInstance instance = new MobEffectInstance(WBMobEffects.DARKNESS.get(), 260, 0, false, false);
MobUtils.addEffectToPlayersWithinDistance(level, entity, pos, range, instance, 200);
MobUtils.addEffectToPlayersWithinDistance(world, entity, pos, range, instance, 200);
}
@Override
public void addAdditionalSaveData(CompoundTag tag) {
super.addAdditionalSaveData(tag);
WardenAngerManager.createCodec(this::isValidTarget).encodeStart(NbtOps.INSTANCE, this.angerManager).resultOrPartial(WildBackport.LOGGER::error).ifPresent(manager -> tag.put("anger", manager));
VibrationListenerSource.codec(this).encodeStart(NbtOps.INSTANCE, this.listener).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> tag.put("listener", listener));
}
@Override
@ -372,8 +371,6 @@ public class Warden extends Monster implements VibrationListenerSource.Vibration
WardenAngerManager.createCodec(this::isValidTarget).parse(new Dynamic<>(NbtOps.INSTANCE, tag.get("anger"))).resultOrPartial(WildBackport.LOGGER::error).ifPresent(manager -> this.angerManager = manager);
this.updateAnger();
}
if (tag.contains("listener", 10)) VibrationListenerSource.codec(this).parse(new Dynamic<>(NbtOps.INSTANCE, tag.getCompound("listener"))).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> this.listener = listener);
}
private void playListeningSound() {
@ -424,7 +421,7 @@ public class Warden extends Monster implements VibrationListenerSource.Vibration
}
@Nullable @Override
public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawn, @Nullable SpawnGroupData groupData, @Nullable CompoundTag tag) {
public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance instance, MobSpawnType spawn, @Nullable SpawnGroupData data, @Nullable CompoundTag tag) {
this.getBrain().setMemoryWithExpiry(WBMemoryModules.DIG_COOLDOWN.get(), Unit.INSTANCE, 1200L);
if (spawn == MobSpawnType.TRIGGERED) {
this.setPose(Poses.EMERGING.get());
@ -432,7 +429,7 @@ public class Warden extends Monster implements VibrationListenerSource.Vibration
this.playSound(WBSoundEvents.WARDEN_AGITATED, 5.0F, 1.0F);
}
return super.finalizeSpawn(level, difficulty, spawn, groupData, tag);
return super.finalizeSpawn(level, instance, spawn, data, tag);
}
@Override

View file

@ -0,0 +1,54 @@
package com.cursedcauldron.wildbackport.common.entities.access;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.level.gameevent.vibrations.VibrationListener;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import java.util.UUID;
public record Vibration(@Nullable UUID uuid, @Nullable UUID sourceUuid, @Nullable Entity entity) {
public Vibration(@Nullable Entity entity) {
this(entity == null ? null : entity.getUUID(), Vibration.getOwnerUuid(entity), entity);
}
@Nullable
private static UUID getOwnerUuid(@Nullable Entity entity) {
if (entity instanceof Projectile projectile && projectile.getOwner() != null) {
return projectile.getOwner().getUUID();
} else {
return null;
}
}
public Optional<Entity> getEntity(ServerLevel level) {
return Optional.ofNullable(this.entity).or(() -> Optional.ofNullable(this.uuid).map(level::getEntity));
}
public Optional<Entity> getOwner(ServerLevel level) {
return Optional.ofNullable(this.entity).filter(entity -> entity instanceof Projectile).map(entity -> (Projectile)entity).map(Projectile::getOwner).or(() -> Optional.ofNullable(this.sourceUuid).map(level::getEntity));
}
public interface Instance {
static Instance of(VibrationListener listener) {
return (Instance)listener;
}
void setPos(BlockPos pos);
BlockPos getPos();
void setEntity(Entity entity);
Entity getEntity();
void setSource(Entity entity);
Entity getSource();
void setVibration(Vibration vibration);
}
}

View file

@ -32,7 +32,7 @@ import java.util.UUID;
//<>
public class VibrationListenerSource implements GameEventListener {
public class VibrationHandler implements GameEventListener {
protected final PositionSource source;
protected final int range;
protected final VibrationConfig config;
@ -40,7 +40,7 @@ public class VibrationListenerSource implements GameEventListener {
protected float distance;
protected int delay;
public static Codec<VibrationListenerSource> codec(VibrationConfig config) {
public static Codec<VibrationHandler> codec(VibrationConfig config) {
return RecordCodecBuilder.create(instance -> {
return instance.group(PositionSource.CODEC.fieldOf("source").forGetter(listener -> {
return listener.source;
@ -53,12 +53,12 @@ public class VibrationListenerSource implements GameEventListener {
}), ExtraCodecs.NON_NEGATIVE_INT.fieldOf("event_delay").orElse(0).forGetter(listener -> {
return listener.delay;
})).apply(instance, (source, range, event, distance, delay) -> {
return new VibrationListenerSource(source, range, config, event.orElse(null), distance, delay);
return new VibrationHandler(source, range, config, event.orElse(null), distance, delay);
});
});
}
public VibrationListenerSource(PositionSource source, int range, VibrationConfig config, @Nullable Vibration event, float distance, int delay) {
public VibrationHandler(PositionSource source, int range, VibrationConfig config, @Nullable Vibration event, float distance, int delay) {
this.source = source;
this.range = range;
this.config = config;
@ -67,6 +67,10 @@ public class VibrationListenerSource implements GameEventListener {
this.delay = delay;
}
public VibrationHandler(PositionSource source, int range, VibrationConfig config) {
this(source, range, config, null, 0.0F, 0);
}
public void tick(Level level) {
if (level instanceof ServerLevel server) {
if (this.event != null) {

View file

@ -0,0 +1,66 @@
package com.cursedcauldron.wildbackport.core.mixin.common;
import com.cursedcauldron.wildbackport.common.entities.access.Vibration;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.gameevent.vibrations.VibrationListener;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(VibrationListener.class)
public class VibrationListenerMixin implements Vibration.Instance {
private BlockPos pos;
private Entity entity;
private Entity source;
private Vibration vibration;
@Inject(method = "handleGameEvent", at = @At("HEAD"))
private void handleSource(Level level, GameEvent event, Entity entity, BlockPos pos, CallbackInfoReturnable<Boolean> cir) {
if (level instanceof ServerLevel server) {
this.setPos(pos);
this.setVibration(new Vibration(entity));
this.setEntity(this.vibration.getEntity(server).orElse(null));
this.setSource(this.vibration.getOwner(server).orElse(null));
}
}
@Override
public void setPos(BlockPos pos) {
this.pos = pos;
}
@Override
public BlockPos getPos() {
return this.pos;
}
@Override
public void setEntity(Entity entity) {
this.entity = entity;
}
@Override
public Entity getEntity() {
return this.entity;
}
@Override
public void setSource(Entity entity) {
this.source = entity;
}
@Override
public Entity getSource() {
return this.source;
}
@Override
public void setVibration(Vibration vibration) {
this.vibration = vibration;
}
}

View file

@ -14,6 +14,7 @@
"access.MobEffectAccessor",
"access.ModelPartAccessor",
"access.OverworldBiomesAccessor",
"access.PersistentEntitySectionManagerAccessor",
"access.PointedDripstoneBlockAccessor",
"access.PressurePlateBlockAccessor",
"access.RecordItemAccessor",
@ -31,16 +32,19 @@
"access.WoodButtonBlockAccessor",
"access.WoodTypeAccessor",
"common.BlockEntityTypeMixin",
"common.EntityCallbacksMixin",
"common.FlyNodeEvaluatorMixin",
"common.LivingEntityMixin",
"common.MobEffectMixin",
"common.MobEffectMixin$MobEffectInstanceMixin",
"common.NoteBlockMixin",
"common.PathfinderMobMixin",
"common.PersistentEntitySectionManagerMixin",
"common.PlayerMixin",
"common.PointedDripstoneBlockMixin",
"common.SculkSensorBlockEntityMixin",
"common.SculkSensorBlockMixin",
"common.VibrationListenerMixin",
"extension.BoatTypeMixin",
"extension.PoseMixin",
"network.ClientboundUpdateMobEffectPacketMixin",

View file

@ -4,6 +4,9 @@ transitive-accessible class net/minecraft/world/level/block/entity/BlockEntityTy
transitive-accessible class net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement$Placer
transitive-accessible class net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement$PieceState
transitive-accessible class net/minecraft/server/level/ServerLevel$EntityCallbacks
transitive-accessible class net/minecraft/world/level/entity/PersistentEntitySectionManager$Callback
transitive-accessible class net/minecraft/core/Registry$RegistryBootstrap
transitive-accessible method net/minecraft/client/particle/HugeExplosionParticle <init> (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDLnet/minecraft/client/particle/SpriteSet;)V

View file

@ -4,6 +4,9 @@ transitive-accessible class net/minecraft/world/level/block/entity/BlockEntityTy
transitive-accessible class net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement$Placer
transitive-accessible class net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement$PieceState
transitive-accessible class net/minecraft/server/level/ServerLevel$EntityCallbacks
transitive-accessible class net/minecraft/world/level/entity/PersistentEntitySectionManager$Callback
transitive-accessible class net/minecraft/core/Registry$RegistryBootstrap
transitive-accessible method net/minecraft/client/particle/HugeExplosionParticle <init> (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDLnet/minecraft/client/particle/SpriteSet;)V