From dbb2a748397a235af2aa1601afcb053fee9c60e0 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sun, 7 Jun 2020 21:34:53 +0200 Subject: [PATCH] Extendo Punch - Players using Extendo Grips can now hurt and interact with entities within the extended range - Hurting entities using Extendo Grips now applies massive knockback --- .../tools/ExtendoGripInteractionPacket.java | 75 ++++++++++ .../curiosities/tools/ExtendoGripItem.java | 129 ++++++++++++++++++ .../tools/ExtendoGripRenderHandler.java | 3 +- .../foundation/networking/AllPackets.java | 2 + 4 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/simibubi/create/content/curiosities/tools/ExtendoGripInteractionPacket.java diff --git a/src/main/java/com/simibubi/create/content/curiosities/tools/ExtendoGripInteractionPacket.java b/src/main/java/com/simibubi/create/content/curiosities/tools/ExtendoGripInteractionPacket.java new file mode 100644 index 000000000..e0f545027 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/tools/ExtendoGripInteractionPacket.java @@ -0,0 +1,75 @@ +package com.simibubi.create.content.curiosities.tools; + +import java.util.function.Supplier; + +import com.simibubi.create.foundation.networking.SimplePacketBase; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.Hand; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.fml.network.NetworkEvent.Context; + +public class ExtendoGripInteractionPacket extends SimplePacketBase { + + private Hand interactionHand; + private int target; + private Vec3d specificPoint; + + public ExtendoGripInteractionPacket(Entity target) { + this(target, null); + } + + public ExtendoGripInteractionPacket(Entity target, Hand hand) { + this(target, hand, null); + } + + public ExtendoGripInteractionPacket(Entity target, Hand hand, Vec3d specificPoint) { + interactionHand = hand; + this.specificPoint = specificPoint; + this.target = target.getEntityId(); + } + + public ExtendoGripInteractionPacket(PacketBuffer buffer) { + target = buffer.readInt(); + int handId = buffer.readInt(); + interactionHand = handId == -1 ? null : Hand.values()[handId]; + if (buffer.readBoolean()) + specificPoint = new Vec3d(buffer.readDouble(), buffer.readDouble(), buffer.readDouble()); + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeInt(target); + buffer.writeInt(interactionHand == null ? -1 : interactionHand.ordinal()); + buffer.writeBoolean(specificPoint != null); + if (specificPoint != null) { + buffer.writeDouble(specificPoint.x); + buffer.writeDouble(specificPoint.y); + buffer.writeDouble(specificPoint.z); + } + } + + @Override + public void handle(Supplier context) { + context.get() + .enqueueWork(() -> { + ServerPlayerEntity sender = context.get() + .getSender(); + Entity entityByID = sender.getServerWorld() + .getEntityByID(target); + if (entityByID != null && ExtendoGripItem.isHoldingExtendoGrip(sender)) { + if (interactionHand == null) + sender.attackTargetEntityWithCurrentItem(entityByID); + else if (specificPoint == null) + sender.interactOn(entityByID, interactionHand); + else + entityByID.applyPlayerInteraction(sender, specificPoint, interactionHand); + } + }); + context.get() + .setPacketHandled(true); + } + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/tools/ExtendoGripItem.java b/src/main/java/com/simibubi/create/content/curiosities/tools/ExtendoGripItem.java index 2bcd745c8..3b6f84580 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/tools/ExtendoGripItem.java +++ b/src/main/java/com/simibubi/create/content/curiosities/tools/ExtendoGripItem.java @@ -6,14 +6,32 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import com.simibubi.create.AllItems; import com.simibubi.create.foundation.advancement.AllTriggers; +import com.simibubi.create.foundation.networking.AllPackets; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.ClientPlayerEntity; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.ai.attributes.AttributeModifier; +import net.minecraft.entity.item.ItemFrameEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.entity.projectile.ProjectileHelper; import net.minecraft.item.Item; import net.minecraft.item.Rarity; import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.DamageSource; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.EntityRayTraceResult; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceResult.Type; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.client.event.InputEvent.ClickInputEvent; import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; +import net.minecraftforge.event.entity.player.AttackEntityEvent; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; @@ -92,4 +110,115 @@ public class ExtendoGripItem extends Item { } + @SubscribeEvent + @OnlyIn(Dist.CLIENT) + public static void dontMissEntitiesWhenYouHaveHighReachDistance(ClickInputEvent event) { + Minecraft mc = Minecraft.getInstance(); + ClientPlayerEntity player = mc.player; + if (mc.world == null || player == null) + return; + + // Modified version of GameRenderer#getMouseOver + double d0 = player.getAttribute(PlayerEntity.REACH_DISTANCE) + .getValue(); + if (!player.isCreative()) + d0 -= 0.5f; + Vec3d vec3d = player.getEyePosition(mc.getRenderPartialTicks()); + Vec3d vec3d1 = player.getLook(1.0F); + Vec3d vec3d2 = vec3d.add(vec3d1.x * d0, vec3d1.y * d0, vec3d1.z * d0); + AxisAlignedBB axisalignedbb = player.getBoundingBox() + .expand(vec3d1.scale(d0)) + .grow(1.0D, 1.0D, 1.0D); + EntityRayTraceResult entityraytraceresult = + ProjectileHelper.rayTraceEntities(player, vec3d, vec3d2, axisalignedbb, (e) -> { + return !e.isSpectator() && e.canBeCollidedWith(); + }, d0 * d0); + if (entityraytraceresult != null) { + Entity entity1 = entityraytraceresult.getEntity(); + Vec3d vec3d3 = entityraytraceresult.getHitVec(); + double d2 = vec3d.squareDistanceTo(vec3d3); + if (d2 < d0 * d0 || mc.objectMouseOver == null || mc.objectMouseOver.getType() == Type.MISS) { + mc.objectMouseOver = entityraytraceresult; + if (entity1 instanceof LivingEntity || entity1 instanceof ItemFrameEntity) + mc.pointedEntity = entity1; + } + } + + } + + @SubscribeEvent + public static void attacksByExtendoGripHaveMoreKnockback(AttackEntityEvent event) { + Entity entity = event.getEntity(); + if (!(entity instanceof PlayerEntity)) + return; + PlayerEntity player = (PlayerEntity) entity; + if (!isHoldingExtendoGrip(player)) + return; + Entity target = event.getTarget(); + if (!target.attackEntityFrom(DamageSource.causePlayerDamage(player), 0)) + return; + int strength = 2; + float yaw = entity.rotationYaw * ((float) Math.PI / 180F); + if (target instanceof LivingEntity) { + ((LivingEntity) target).knockBack(entity, strength, MathHelper.sin(yaw), -MathHelper.cos(yaw)); + return; + } + target.addVelocity(-MathHelper.sin(yaw) * strength, 0.1D, MathHelper.cos(yaw) * strength); + } + + private static boolean isUncaughtClientInteraction(Entity entity, Entity target) { + // Server ignores entity interaction further than 6m + if (entity.getDistanceSq(target) < 36) + return false; + if (!entity.world.isRemote) + return false; + if (!(entity instanceof PlayerEntity)) + return false; + return true; + } + + @SubscribeEvent + @OnlyIn(Dist.CLIENT) + public static void notifyServerOfLongRangeAttacks(AttackEntityEvent event) { + Entity entity = event.getEntity(); + Entity target = event.getTarget(); + if (!isUncaughtClientInteraction(entity, target)) + return; + PlayerEntity player = (PlayerEntity) entity; + if (isHoldingExtendoGrip(player)) + AllPackets.channel.sendToServer(new ExtendoGripInteractionPacket(target)); + } + + @SubscribeEvent + @OnlyIn(Dist.CLIENT) + public static void notifyServerOfLongRangeInteractions(PlayerInteractEvent.EntityInteract event) { + Entity entity = event.getEntity(); + Entity target = event.getTarget(); + if (!isUncaughtClientInteraction(entity, target)) + return; + PlayerEntity player = (PlayerEntity) entity; + if (isHoldingExtendoGrip(player)) + AllPackets.channel.sendToServer(new ExtendoGripInteractionPacket(target, event.getHand())); + } + + @SubscribeEvent + @OnlyIn(Dist.CLIENT) + public static void notifyServerOfLongRangeSpecificInteractions(PlayerInteractEvent.EntityInteractSpecific event) { + Entity entity = event.getEntity(); + Entity target = event.getTarget(); + if (!isUncaughtClientInteraction(entity, target)) + return; + PlayerEntity player = (PlayerEntity) entity; + if (isHoldingExtendoGrip(player)) + AllPackets.channel + .sendToServer(new ExtendoGripInteractionPacket(target, event.getHand(), event.getLocalPos())); + } + + public static boolean isHoldingExtendoGrip(PlayerEntity player) { + boolean inOff = AllItems.EXTENDO_GRIP.isIn(player.getHeldItemOffhand()); + boolean inMain = AllItems.EXTENDO_GRIP.isIn(player.getHeldItemMainhand()); + boolean holdingGrip = inOff || inMain; + return holdingGrip; + } + } diff --git a/src/main/java/com/simibubi/create/content/curiosities/tools/ExtendoGripRenderHandler.java b/src/main/java/com/simibubi/create/content/curiosities/tools/ExtendoGripRenderHandler.java index f52dbfc5d..e82d9ec54 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/tools/ExtendoGripRenderHandler.java +++ b/src/main/java/com/simibubi/create/content/curiosities/tools/ExtendoGripRenderHandler.java @@ -16,12 +16,13 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.Hand; import net.minecraft.util.HandSide; import net.minecraft.util.math.MathHelper; +import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.ForgeHooksClient; import net.minecraftforge.client.event.RenderHandEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; -@EventBusSubscriber +@EventBusSubscriber(value = Dist.CLIENT) public class ExtendoGripRenderHandler { public static float mainHandAnimation; diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index e9612a943..40a1376d2 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -10,6 +10,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Con import com.simibubi.create.content.contraptions.components.structureMovement.glue.GlueEffectPacket; import com.simibubi.create.content.contraptions.relays.advanced.sequencer.ConfigureSequencedGearshiftPacket; import com.simibubi.create.content.curiosities.symmetry.SymmetryEffectPacket; +import com.simibubi.create.content.curiosities.tools.ExtendoGripInteractionPacket; import com.simibubi.create.content.curiosities.zapper.ZapperBeamPacket; import com.simibubi.create.content.logistics.item.filter.FilterScreenPacket; import com.simibubi.create.content.logistics.packet.ConfigureFlexcratePacket; @@ -42,6 +43,7 @@ public enum AllPackets { CONFIGURE_FILTERING_AMOUNT(FilteringCountUpdatePacket.class, FilteringCountUpdatePacket::new), CONFIGURE_SCROLLABLE(ScrollValueUpdatePacket.class, ScrollValueUpdatePacket::new), CANCEL_FALL(CancelPlayerFallPacket.class, CancelPlayerFallPacket::new), + EXTENDO_INTERACT(ExtendoGripInteractionPacket.class, ExtendoGripInteractionPacket::new), // Server to Client SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new),