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
This commit is contained in:
simibubi 2020-06-07 21:34:53 +02:00
parent ba81d391e7
commit dbb2a74839
4 changed files with 208 additions and 1 deletions

View file

@ -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) {
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);
}
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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),