NaturesAura/src/main/java/de/ellpeck/naturesaura/items/ItemPetReviver.java

134 lines
6.7 KiB
Java
Raw Normal View History

2020-09-30 03:03:29 +02:00
package de.ellpeck.naturesaura.items;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticles;
2021-12-15 16:24:53 +01:00
import net.minecraft.ChatFormatting;
import net.minecraft.core.particles.ParticleTypes;
2022-06-27 15:24:04 +02:00
import net.minecraft.network.chat.Component;
2021-12-15 16:24:53 +01:00
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.TamableAnimal;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.Vec3;
2020-09-30 03:03:29 +02:00
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.living.LivingDeathEvent;
import net.minecraftforge.event.entity.living.LivingEvent;
2020-09-30 03:03:29 +02:00
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
public class ItemPetReviver extends ItemImpl {
2021-12-15 16:24:53 +01:00
2020-09-30 03:03:29 +02:00
public ItemPetReviver() {
super("pet_reviver");
MinecraftForge.EVENT_BUS.register(new Events());
}
private static class Events {
@SubscribeEvent
public void onEntityTick(LivingEvent.LivingTickEvent event) {
var entity = event.getEntity();
2023-07-08 12:32:27 +02:00
if (entity.level().isClientSide || entity.level().getGameTime() % 20 != 0 || !(entity instanceof TamableAnimal tameable))
return;
2021-12-15 16:24:53 +01:00
if (!tameable.isTame() || !tameable.getPersistentData().getBoolean(NaturesAura.MOD_ID + ":pet_reviver"))
return;
2021-12-15 16:30:22 +01:00
var owner = tameable.getOwner();
2021-12-15 16:24:53 +01:00
if (owner == null || owner.distanceToSqr(tameable) > 5 * 5)
return;
2023-07-08 12:32:27 +02:00
if (entity.level().random.nextFloat() >= 0.65F) {
((ServerLevel) entity.level()).sendParticles(ParticleTypes.HEART,
entity.getX() + entity.level().random.nextGaussian() * 0.25F,
entity.getEyeY() + entity.level().random.nextGaussian() * 0.25F,
entity.getZ() + entity.level().random.nextGaussian() * 0.25F,
entity.level().random.nextInt(2) + 1, 0, 0, 0, 0);
}
}
2021-12-15 16:24:53 +01:00
// we need to use the event since the item doesn't receive the interaction for tamed pets...
2020-09-30 03:03:29 +02:00
@SubscribeEvent
public void onEntityInteract(PlayerInteractEvent.EntityInteractSpecific event) {
2021-12-15 16:30:22 +01:00
var target = event.getTarget();
2021-12-15 16:24:53 +01:00
if (!(target instanceof TamableAnimal) || !((TamableAnimal) target).isTame())
2020-09-30 03:03:29 +02:00
return;
if (target.getPersistentData().getBoolean(NaturesAura.MOD_ID + ":pet_reviver"))
return;
var stack = event.getEntity().getItemInHand(event.getHand());
2020-09-30 03:03:29 +02:00
if (stack.getItem() != ModItems.PET_REVIVER)
return;
target.getPersistentData().putBoolean(NaturesAura.MOD_ID + ":pet_reviver", true);
2023-07-08 12:32:27 +02:00
if (!target.level().isClientSide)
stack.shrink(1);
2021-12-04 15:40:09 +01:00
event.setCancellationResult(InteractionResult.SUCCESS);
2020-09-30 03:03:29 +02:00
event.setCanceled(true);
}
// we want to be sure that the pet is really dying, so we want to receive the event last
@SubscribeEvent(priority = EventPriority.LOWEST)
public void onLivingDeath(LivingDeathEvent event) {
var entity = event.getEntity();
2023-07-08 12:32:27 +02:00
if (entity.level().isClientSide || !(entity instanceof TamableAnimal tameable))
2020-09-30 03:03:29 +02:00
return;
2021-12-15 16:24:53 +01:00
if (!tameable.isTame() || !tameable.getPersistentData().getBoolean(NaturesAura.MOD_ID + ":pet_reviver"))
2020-09-30 03:03:29 +02:00
return;
// get the overworld, and the overworld's spawn point, by default
2023-07-08 12:32:27 +02:00
var spawnLevel = tameable.level().getServer().overworld();
2021-12-15 16:30:22 +01:00
var spawn = Vec3.atBottomCenterOf(spawnLevel.getSharedSpawnPos());
2020-09-30 03:03:29 +02:00
// check if the owner is online, and respawn at the bed if they are
2021-12-15 16:30:22 +01:00
var owner = tameable.getOwner();
2021-12-15 16:24:53 +01:00
if (owner instanceof ServerPlayer player) {
2021-12-15 16:30:22 +01:00
var pos = player.getRespawnPosition();
2020-09-30 03:03:29 +02:00
if (pos != null) {
2021-12-15 16:30:22 +01:00
var f = player.getRespawnAngle();
var b = player.isRespawnForced();
2023-07-08 12:32:27 +02:00
var bed = Player.findRespawnPositionAndUseSpawnBlock((ServerLevel) player.level(), pos, f, b, false);
2020-09-30 03:03:29 +02:00
if (bed.isPresent()) {
2023-07-08 12:32:27 +02:00
spawnLevel = (ServerLevel) player.level();
2020-09-30 03:03:29 +02:00
spawn = bed.get();
}
}
}
2023-07-08 12:32:27 +02:00
PacketHandler.sendToAllAround(tameable.level(), tameable.blockPosition(), 32, new PacketParticles((float) tameable.getX(), (float) tameable.getEyeY(), (float) tameable.getZ(), PacketParticles.Type.PET_REVIVER, 0xc2461d));
2020-09-30 03:03:29 +02:00
2021-12-15 16:30:22 +01:00
var spawnedPet = tameable;
2023-07-08 12:32:27 +02:00
if (tameable.level() != spawnLevel) {
2022-06-27 15:24:04 +02:00
tameable.remove(Entity.RemovalReason.DISCARDED);
2021-12-15 16:24:53 +01:00
spawnedPet = (TamableAnimal) tameable.getType().create(spawnLevel);
2020-09-30 03:03:29 +02:00
}
// respawn (a copy of) the pet
2021-12-15 16:24:53 +01:00
spawnedPet.restoreFrom(tameable);
spawnedPet.setDeltaMovement(0, 0, 0);
spawnedPet.moveTo(spawn.x, spawn.y, spawn.z, tameable.getYRot(), tameable.getXRot());
while (!spawnLevel.noCollision(spawnedPet))
spawnedPet.setPos(spawnedPet.getX(), spawnedPet.getY() + 1, spawnedPet.getZ());
2020-09-30 03:03:29 +02:00
spawnedPet.setHealth(spawnedPet.getMaxHealth());
2021-12-15 16:24:53 +01:00
spawnedPet.getNavigation().stop();
2020-09-30 03:03:29 +02:00
// sit down (on the server side!)
2021-12-15 16:24:53 +01:00
spawnedPet.setInSittingPose(true);
2020-09-30 03:03:29 +02:00
spawnedPet.setJumping(false);
2021-12-15 16:24:53 +01:00
spawnedPet.setTarget(null);
2023-07-08 12:32:27 +02:00
if (tameable.level() != spawnLevel) {
2021-12-15 16:24:53 +01:00
spawnLevel.addFreshEntity(spawnedPet);
tameable.remove(Entity.RemovalReason.DISCARDED);
2020-09-30 03:03:29 +02:00
}
// drain aura
2021-12-15 16:30:22 +01:00
var auraPos = IAuraChunk.getHighestSpot(spawnLevel, spawnedPet.blockPosition(), 35, spawnedPet.blockPosition());
2021-12-04 15:40:09 +01:00
IAuraChunk.getAuraChunk(spawnLevel, auraPos).drainAura(auraPos, 200000);
2020-09-30 03:03:29 +02:00
2023-07-08 12:32:27 +02:00
PacketHandler.sendToAllAround(spawnedPet.level(), spawnedPet.blockPosition(), 32, new PacketParticles((float) spawnedPet.getX(), (float) spawnedPet.getEyeY(), (float) spawnedPet.getZ(), PacketParticles.Type.PET_REVIVER, 0x4dba2f));
2020-09-30 03:03:29 +02:00
2021-12-04 15:40:09 +01:00
if (owner instanceof Player)
2022-06-27 15:24:04 +02:00
owner.sendSystemMessage(Component.translatable("info." + NaturesAura.MOD_ID + ".pet_reviver", spawnedPet.getDisplayName()).withStyle(ChatFormatting.ITALIC, ChatFormatting.GRAY));
2020-09-30 03:03:29 +02:00
event.setCanceled(true);
}
}
}