mirror of
https://github.com/Ellpeck/NaturesAura.git
synced 2024-11-25 20:58:34 +01:00
pet reviver, part 1
This commit is contained in:
parent
3e4aa9c757
commit
68bc3c6af2
5 changed files with 139 additions and 1 deletions
123
src/main/java/de/ellpeck/naturesaura/items/ItemPetReviver.java
Normal file
123
src/main/java/de/ellpeck/naturesaura/items/ItemPetReviver.java
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
package de.ellpeck.naturesaura.items;
|
||||||
|
|
||||||
|
import de.ellpeck.naturesaura.NaturesAura;
|
||||||
|
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
|
||||||
|
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;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
|
import net.minecraft.entity.player.SpawnLocationHelper;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.ActionResultType;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
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;
|
||||||
|
import net.minecraft.world.server.ServerWorld;
|
||||||
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
import net.minecraftforge.event.entity.living.LivingDeathEvent;
|
||||||
|
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 {
|
||||||
|
|
||||||
|
// 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))
|
||||||
|
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);
|
||||||
|
stack.shrink(1);
|
||||||
|
event.setCancellationResult(ActionResultType.SUCCESS);
|
||||||
|
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();
|
||||||
|
if (entity.world.isRemote || !(entity instanceof TameableEntity))
|
||||||
|
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
|
||||||
|
ServerWorld spawnWorld = tameable.world.getServer().func_241755_D_();
|
||||||
|
Vector3d spawn = Vector3d.copyCenteredHorizontally(spawnWorld.func_241135_u_());
|
||||||
|
|
||||||
|
// check if the owner is online, and respawn at the bed if they are
|
||||||
|
LivingEntity owner = tameable.getOwner();
|
||||||
|
if (owner instanceof ServerPlayerEntity) {
|
||||||
|
ServerPlayerEntity player = (ServerPlayerEntity) owner;
|
||||||
|
|
||||||
|
// 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_();
|
||||||
|
Optional<Vector3d> bed = PlayerEntity.func_242374_a((ServerWorld) player.world, pos, f, b, false);
|
||||||
|
if (bed.isPresent()) {
|
||||||
|
spawnWorld = (ServerWorld) player.world;
|
||||||
|
spawn = bed.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketHandler.sendToAllAround(tameable.world, tameable.getPosition(), 32, new PacketParticles((float) tameable.getPosX(), (float) tameable.getPosYEye(), (float) tameable.getPosZ(), PacketParticles.Type.PET_REVIVER, 0xc2461d));
|
||||||
|
|
||||||
|
TameableEntity spawnedPet = tameable;
|
||||||
|
if (tameable.world != spawnWorld) {
|
||||||
|
((ServerWorld) tameable.world).removeEntity(tameable, true);
|
||||||
|
spawnedPet = (TameableEntity) tameable.getType().create(spawnWorld);
|
||||||
|
}
|
||||||
|
// 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);
|
||||||
|
while (!spawnWorld.hasNoCollisions(spawnedPet))
|
||||||
|
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);
|
||||||
|
if (tameable.world != spawnWorld) {
|
||||||
|
spawnWorld.addEntity(spawnedPet);
|
||||||
|
tameable.remove(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// drain aura
|
||||||
|
BlockPos auraPos = IAuraChunk.getHighestSpot(spawnWorld, spawnedPet.getPosition(), 35, spawnedPet.getPosition());
|
||||||
|
IAuraChunk.getAuraChunk(spawnWorld, auraPos).drainAura(auraPos, 200000);
|
||||||
|
|
||||||
|
PacketHandler.sendToAllAround(spawnedPet.world, spawnedPet.getPosition(), 32, new PacketParticles((float) spawnedPet.getPosX(), (float) spawnedPet.getPosYEye(), (float) spawnedPet.getPosZ(), PacketParticles.Type.PET_REVIVER, 0x4dba2f));
|
||||||
|
|
||||||
|
if (owner instanceof PlayerEntity)
|
||||||
|
owner.sendMessage(new TranslationTextComponent("info." + NaturesAura.MOD_ID + ".pet_reviver", spawnedPet.getDisplayName()).mergeStyle(TextFormatting.ITALIC, TextFormatting.GRAY), UUID.randomUUID());
|
||||||
|
event.setCanceled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,4 +61,5 @@ public final class ModItems {
|
||||||
public static Item FORTRESS_FINDER;
|
public static Item FORTRESS_FINDER;
|
||||||
public static Item END_CITY_FINDER;
|
public static Item END_CITY_FINDER;
|
||||||
public static Item BREAK_PREVENTION;
|
public static Item BREAK_PREVENTION;
|
||||||
|
public static Item PET_REVIVER;
|
||||||
}
|
}
|
||||||
|
|
|
@ -566,6 +566,17 @@ public class PacketParticles {
|
||||||
message.posY + (float) world.rand.nextGaussian() * 0.5F,
|
message.posY + (float) world.rand.nextGaussian() * 0.5F,
|
||||||
message.posZ + (float) world.rand.nextGaussian() * 0.5F,
|
message.posZ + (float) world.rand.nextGaussian() * 0.5F,
|
||||||
x + 0.5F, y + 0.5F, z + 0.5F, 0.2F, color, world.rand.nextFloat() + 1);
|
x + 0.5F, y + 0.5F, z + 0.5F, 0.2F, color, world.rand.nextFloat() + 1);
|
||||||
|
}),
|
||||||
|
PET_REVIVER((message, world) -> {
|
||||||
|
for (int i = world.rand.nextInt(50) + 150; i >= 0; i--)
|
||||||
|
NaturesAuraAPI.instance().spawnMagicParticle(
|
||||||
|
message.posX + (float) world.rand.nextGaussian() * 0.4F,
|
||||||
|
message.posY + (float) world.rand.nextGaussian() * 0.4F,
|
||||||
|
message.posZ + (float) world.rand.nextGaussian() * 0.4F,
|
||||||
|
world.rand.nextGaussian() * 0.002F,
|
||||||
|
world.rand.nextFloat() * 0.001F + 0.002F,
|
||||||
|
world.rand.nextGaussian() * 0.002F,
|
||||||
|
message.data[0], world.rand.nextFloat() * 2 + 1, world.rand.nextInt(50) + 50, 0, false, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
public final BiConsumer<PacketParticles, World> action;
|
public final BiConsumer<PacketParticles, World> action;
|
||||||
|
|
|
@ -222,7 +222,8 @@ public final class ModRegistry {
|
||||||
new ItemArmor("sky_shoes", ModArmorMaterial.SKY, EquipmentSlotType.FEET),
|
new ItemArmor("sky_shoes", ModArmorMaterial.SKY, EquipmentSlotType.FEET),
|
||||||
new ItemStructureFinder("fortress_finder", Structure.field_236378_n_, 0xba2800),
|
new ItemStructureFinder("fortress_finder", Structure.field_236378_n_, 0xba2800),
|
||||||
new ItemStructureFinder("end_city_finder", Structure.field_236379_o_, 0xca5cd6),
|
new ItemStructureFinder("end_city_finder", Structure.field_236379_o_, 0xca5cd6),
|
||||||
new ItemBreakPrevention()
|
new ItemBreakPrevention(),
|
||||||
|
new ItemPetReviver()
|
||||||
);
|
);
|
||||||
Helper.populateObjectHolders(ModItems.class, event.getRegistry());
|
Helper.populateObjectHolders(ModItems.class, event.getRegistry());
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,7 @@
|
||||||
"item.naturesaura.fortress_finder": "Eye of the Blaze",
|
"item.naturesaura.fortress_finder": "Eye of the Blaze",
|
||||||
"item.naturesaura.end_city_finder": "Eye of the Shulker",
|
"item.naturesaura.end_city_finder": "Eye of the Shulker",
|
||||||
"item.naturesaura.break_prevention": "Eir's Token",
|
"item.naturesaura.break_prevention": "Eir's Token",
|
||||||
|
"item.naturesaura.pet_reviver": "Token of Undying Friendship",
|
||||||
"container.naturesaura:tree_ritual.name": "Ritual of the Forest",
|
"container.naturesaura:tree_ritual.name": "Ritual of the Forest",
|
||||||
"container.naturesaura:altar.name": "Natural Altar Infusion",
|
"container.naturesaura:altar.name": "Natural Altar Infusion",
|
||||||
"container.naturesaura:offering.name": "Offering to the Gods",
|
"container.naturesaura:offering.name": "Offering to the Gods",
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
"info.naturesaura.broken": " (Broken)",
|
"info.naturesaura.broken": " (Broken)",
|
||||||
"info.naturesaura.required_aura_type.naturesaura:overworld": "Requires Natural Altar",
|
"info.naturesaura.required_aura_type.naturesaura:overworld": "Requires Natural Altar",
|
||||||
"info.naturesaura.required_aura_type.naturesaura:nether": "Requires Crimson Altar",
|
"info.naturesaura.required_aura_type.naturesaura:nether": "Requires Crimson Altar",
|
||||||
|
"info.naturesaura.pet_reviver": "Your pet %s was in distress and has been sent home.",
|
||||||
"advancement.naturesaura.root": "Nature's Aura",
|
"advancement.naturesaura.root": "Nature's Aura",
|
||||||
"advancement.naturesaura.root.desc": "Becoming a magical botanist",
|
"advancement.naturesaura.root.desc": "Becoming a magical botanist",
|
||||||
"advancement.naturesaura.get_book": "Pages of Discovery",
|
"advancement.naturesaura.get_book": "Pages of Discovery",
|
||||||
|
|
Loading…
Reference in a new issue