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

143 lines
7.2 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;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.passive.TameableEntity;
2021-12-04 15:40:09 +01:00
import net.minecraft.entity.player.Player;
import net.minecraft.entity.player.ServerPlayer;
2020-09-30 03:03:29 +02:00
import net.minecraft.item.ItemStack;
import net.minecraft.particles.ParticleTypes;
2021-12-04 15:40:09 +01:00
import net.minecraft.util.InteractionResult;
2020-09-30 03:03:29 +02:00
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent;
2021-12-04 15:40:09 +01:00
import net.minecraft.level.server.ServerLevel;
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;
import java.util.Optional;
import java.util.UUID;
public class ItemPetReviver extends ItemImpl {
public ItemPetReviver() {
super("pet_reviver");
MinecraftForge.EVENT_BUS.register(new Events());
}
private static class Events {
@SubscribeEvent
public void onEntityTick(LivingEvent.LivingUpdateEvent event) {
LivingEntity entity = event.getEntityLiving();
2021-12-04 15:40:09 +01:00
if (entity.level.isClientSide || entity.level.getGameTime() % 20 != 0 || !(entity instanceof TameableEntity))
return;
TameableEntity tameable = (TameableEntity) entity;
if (!tameable.isTamed() || !tameable.getPersistentData().getBoolean(NaturesAura.MOD_ID + ":pet_reviver"))
return;
LivingEntity owner = tameable.getOwner();
if (owner == null || owner.getDistanceSq(tameable) > 5 * 5)
return;
2021-12-04 15:40:09 +01:00
if (entity.level.rand.nextFloat() >= 0.65F) {
((ServerLevel) entity.level).spawnParticle(ParticleTypes.HEART,
entity.getPosX() + entity.level.rand.nextGaussian() * 0.25F,
entity.getPosYEye() + entity.level.rand.nextGaussian() * 0.25F,
entity.getPosZ() + entity.level.rand.nextGaussian() * 0.25F,
entity.level.rand.nextInt(2) + 1, 0, 0, 0, 0);
}
}
2020-09-30 03:03:29 +02:00
// we need to use the event since the item doesn't receive the interaction for tamed pets..
@SubscribeEvent
public void onEntityInteract(PlayerInteractEvent.EntityInteractSpecific event) {
Entity target = event.getTarget();
if (!(target instanceof TameableEntity) || !((TameableEntity) target).isTamed())
2020-09-30 03:03:29 +02:00
return;
if (target.getPersistentData().getBoolean(NaturesAura.MOD_ID + ":pet_reviver"))
return;
ItemStack stack = event.getPlayer().getHeldItem(event.getHand());
if (stack.getItem() != ModItems.PET_REVIVER)
return;
target.getPersistentData().putBoolean(NaturesAura.MOD_ID + ":pet_reviver", true);
2021-12-04 15:40:09 +01: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) {
LivingEntity entity = event.getEntityLiving();
2021-12-04 15:40:09 +01:00
if (entity.level.isClientSide || !(entity instanceof TameableEntity))
2020-09-30 03:03:29 +02:00
return;
TameableEntity tameable = (TameableEntity) entity;
if (!tameable.isTamed() || !tameable.getPersistentData().getBoolean(NaturesAura.MOD_ID + ":pet_reviver"))
return;
// get the overworld, and the overworld's spawn point, by default
2021-12-04 15:40:09 +01:00
ServerLevel spawnLevel = tameable.level.getServer().func_241755_D_();
Vector3d spawn = Vector3d.copyCenteredHorizontally(spawnLevel.func_241135_u_());
2020-09-30 03:03:29 +02:00
// check if the owner is online, and respawn at the bed if they are
LivingEntity owner = tameable.getOwner();
2021-12-04 15:40:09 +01:00
if (owner instanceof ServerPlayer) {
ServerPlayer player = (ServerPlayer) owner;
2020-09-30 03:03:29 +02:00
// I'm not really sure what this means, but I got it from PlayerList.func_232644_a_ haha
BlockPos pos = player.func_241140_K_();
if (pos != null) {
float f = player.func_242109_L();
boolean b = player.func_241142_M_();
2021-12-04 15:40:09 +01:00
Optional<Vector3d> bed = Player.func_242374_a((ServerLevel) player.level, pos, f, b, false);
2020-09-30 03:03:29 +02:00
if (bed.isPresent()) {
2021-12-04 15:40:09 +01:00
spawnLevel = (ServerLevel) player.level;
2020-09-30 03:03:29 +02:00
spawn = bed.get();
}
}
}
2021-12-04 15:40:09 +01:00
PacketHandler.sendToAllAround(tameable.level, tameable.getPosition(), 32, new PacketParticles((float) tameable.getPosX(), (float) tameable.getPosYEye(), (float) tameable.getPosZ(), PacketParticles.Type.PET_REVIVER, 0xc2461d));
2020-09-30 03:03:29 +02:00
TameableEntity spawnedPet = tameable;
2021-12-04 15:40:09 +01:00
if (tameable.level != spawnLevel) {
((ServerLevel) tameable.level).removeEntity(tameable, true);
spawnedPet = (TameableEntity) tameable.getType().create(spawnLevel);
2020-09-30 03:03:29 +02:00
}
// respawn (a copy of) the pet
spawnedPet.copyDataFromOld(tameable);
spawnedPet.setMotion(0, 0, 0);
spawnedPet.setLocationAndAngles(spawn.x, spawn.y, spawn.z, tameable.rotationYaw, tameable.rotationPitch);
2021-12-04 15:40:09 +01:00
while (!spawnLevel.hasNoCollisions(spawnedPet))
2020-09-30 03:03:29 +02:00
spawnedPet.setPosition(spawnedPet.getPosX(), spawnedPet.getPosY() + 1, spawnedPet.getPosZ());
spawnedPet.setHealth(spawnedPet.getMaxHealth());
spawnedPet.getNavigator().clearPath();
// sit down (on the server side!)
spawnedPet.func_233687_w_(true);
spawnedPet.setJumping(false);
spawnedPet.setAttackTarget(null);
2021-12-04 15:40:09 +01:00
if (tameable.level != spawnLevel) {
spawnLevel.addEntity(spawnedPet);
2020-09-30 03:03:29 +02:00
tameable.remove(false);
}
// drain aura
2021-12-04 15:40:09 +01:00
BlockPos auraPos = IAuraChunk.getHighestSpot(spawnLevel, spawnedPet.getPosition(), 35, spawnedPet.getPosition());
IAuraChunk.getAuraChunk(spawnLevel, auraPos).drainAura(auraPos, 200000);
2020-09-30 03:03:29 +02:00
2021-12-04 15:40:09 +01:00
PacketHandler.sendToAllAround(spawnedPet.level, spawnedPet.getPosition(), 32, new PacketParticles((float) spawnedPet.getPosX(), (float) spawnedPet.getPosYEye(), (float) spawnedPet.getPosZ(), 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)
2020-09-30 03:03:29 +02:00
owner.sendMessage(new TranslationTextComponent("info." + NaturesAura.MOD_ID + ".pet_reviver", spawnedPet.getDisplayName()).mergeStyle(TextFormatting.ITALIC, TextFormatting.GRAY), UUID.randomUUID());
event.setCanceled(true);
}
}
}