Jump to content

[1.15.1] How could I create a "catch projectile" type of behavior on a player?


Recommended Posts

Posted

How could I make behavior on the player that when the player sees the projectile "catches it" e.g a skeleton shoots the player but if the player is facing the arrow the player catches the projectile so far the event I think it has to do something with it is ProjectileImpactEvent, however, I'm not entirely sure how could I write that behavior. Here's my code

 

@SubscribeEvent
public static void onProjectileCatchEvent(ProjectileImpactEvent event) {

    if (event.getEntity() instanceof ArrowEntity) {
     event.setCanceled(true);
    }
}

 

Posted

From AbstractArrowEntity::tick

EntityRayTraceResult entityraytraceresult = this.rayTraceEntities(vec3d2, vec3d3);
if (entityraytraceresult != null) {
   raytraceresult = entityraytraceresult;
}

if (raytraceresult != null && raytraceresult.getType() == RayTraceResult.Type.ENTITY) {
   Entity entity = ((EntityRayTraceResult)raytraceresult).getEntity();
   Entity entity1 = this.getShooter();
   if (entity instanceof PlayerEntity && entity1 instanceof PlayerEntity && !((PlayerEntity)entity1).canAttackPlayer((PlayerEntity)entity)) {
      raytraceresult = null;
      entityraytraceresult = null;
   }
}

if (raytraceresult != null && raytraceresult.getType() != RayTraceResult.Type.MISS && !flag && !net.minecraftforge.event.ForgeEventFactory.onProjectileImpact(this, raytraceresult)) {
   this.onHit(raytraceresult);
   this.isAirBorne = true;
}

The event is fired in that fourth if statement. You should be able to get the Enity the arrow hit (if any) from the EntityRayTraceResult. Then I suppose you'll want to find out if the Entity is a player and if they were facing the appropriate direction at the time.

  • Thanks 1
Posted
8 hours ago, MoxLotus said:

From AbstractArrowEntity::tick


EntityRayTraceResult entityraytraceresult = this.rayTraceEntities(vec3d2, vec3d3);
if (entityraytraceresult != null) {
   raytraceresult = entityraytraceresult;
}

if (raytraceresult != null && raytraceresult.getType() == RayTraceResult.Type.ENTITY) {
   Entity entity = ((EntityRayTraceResult)raytraceresult).getEntity();
   Entity entity1 = this.getShooter();
   if (entity instanceof PlayerEntity && entity1 instanceof PlayerEntity && !((PlayerEntity)entity1).canAttackPlayer((PlayerEntity)entity)) {
      raytraceresult = null;
      entityraytraceresult = null;
   }
}

if (raytraceresult != null && raytraceresult.getType() != RayTraceResult.Type.MISS && !flag && !net.minecraftforge.event.ForgeEventFactory.onProjectileImpact(this, raytraceresult)) {
   this.onHit(raytraceresult);
   this.isAirBorne = true;
}

The event is fired in that fourth if statement. You should be able to get the Enity the arrow hit (if any) from the EntityRayTraceResult. Then I suppose you'll want to find out if the Entity is a player and if they were facing the appropriate direction at the time.

Hi, thanks for the tip, tried to implement it to my code but I just can't seem to get it to work, tried to do it without the condition of the player looking at it for testing purposes and I just couldn't make it work, do you have any idea why? Here's my code: 

@SubscribeEvent
public static void onProjectileHitEvent(ProjectileImpactEvent event) {


        EntityRayTraceResult entityRayTraceResult = new EntityRayTraceResult(event.getEntity(), event.getRayTraceResult().getHitVec());

        Entity entity = entityRayTraceResult.getEntity();

        if (entity instanceof PlayerEntity) {

            PlayerEntity playerEntity = (PlayerEntity) entity;
            if (playerEntity.getItemStackFromSlot(EquipmentSlotType.CHEST).getItem() == ItemHolder.BATMAN_CHEST) {
                event.setCanceled(true);
            }

        }
    }
Posted

Instead of creating a new RayTraceResult you should have an instanceof test and cast event.getRayTraceResult.

 

As for your question, does it do what you expect if you always cancel the event?

  • Thanks 1
Posted
10 hours ago, MoxLotus said:

Instead of creating a new RayTraceResult you should have an instanceof test and cast event.getRayTraceResult.

 

As for your question, does it do what you expect if you always cancel the event?

Got it, thanks! no, it was just for testing purposes now I got to figure out the "catch" also I noticed that with this code if I get hit by 2 arrows consecutively it crashes:

@SubscribeEvent
public static void onProjectileHitEvent(ProjectileImpactEvent event) {


        if (event.getRayTraceResult() instanceof EntityRayTraceResult) {
            EntityRayTraceResult entityRayTraceResult = (EntityRayTraceResult) event.getRayTraceResult();

            if (entityRayTraceResult.getEntity() instanceof PlayerEntity) {

                PlayerEntity playerEntity = (PlayerEntity) entityRayTraceResult.getEntity();
                if (playerEntity.getItemStackFromSlot(EquipmentSlotType.CHEST).getItem() == ItemHolder.BATMAN_CHEST) {

                    event.setCanceled(true);

                }

                 }
            }
        }
Posted

Any helpful crash logs? I can't give much insight without those.

It's not convenient for me to dig through code right now, but somewhere in Entity or EntityLiving there should be functions that deal with which direction the entity is looking in. Maybe try finding examples in the Enderman code, since line of sight is so important to them. If you can find it, figuring out if the ray-trace from the arrow came from the appropriate direction should just be a question of math.

Do my sense of aesthetic a favor and combine those first two if statements with a &&. That way you cast your two variables only if you actually need them.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hi, I've been having trouble trying to use forge as it shows a black screen when I open the game, but I can still interact with it and hear the music.  I've done all of the step by steps and most common fixes like updating drivers, keeping up to date with Java, deleting and reinstalling minecraft, restarting my computer MANY times, even smaller things like splash.properties (I didn't have that file so I added it and set it to false thinking it would do something, definitely not) and making sure to prioritize my rtx 3070 in the settings but with no luck. Minecraft works as intended when I uninstall forge and I also don't have any mods currently, it just gives me this issue when I install forge. I also increased the ram usage, made sure my hardware isn't full or anything, and even changed the resolution in hopes it would fix things. I checked my antivirus and firewall but that isn't the issue either. Trust me, I've done everything I can think of. For some reason the black screen does flicker a little into the main menu, but obviously unplayable. I couldn't even make my way to the settings with how little it flickered. I'm not sure if it flickered randomly or if it was because I was messing around moving and clicking a bunch, I didn't really test it that much.  
    • I've had a really weird issue recently,  I wanted to add the Depper and Darker mod on my dedicated server (MC 1.21 with Fabric 0.16.9, hosted on nitroserv.com) but whenever I do add the mod the sever stops doing anything after listing the mods, and I get no crash or error or anything, just a stuck server. Here's a normal log of the server booting up: https://pastebin.com/JipFF2Eh and here's the log of the server doing the weird thing: https://pastebin.com/W4JBh3eX I just don't understand it. I've tried removing other mods (somewhat randomly) but deeper and darker still breaks my server whenever I add it. NitroServ support staff is about as confused as I am and I've had no response from the Deeper and Darker support staff... Now I know this is the Forge support not the Fabric support but I'm just trying to know if anyone has any kind of idea to fix this (aside from not using the mod obviously) Also I still have a bunch of errors and warnings whenever the server does start properly, are there any of them I should be worried about?
    • Delete the config of RandomTweaker (config folder) If there is no change, remove this mod
    • Hello! So i have been trying to make a mod that adds plant fiber to minecraft 1.16.5 (i believe there are mods that add plant fiber but not for 1.16.5) but the problem is that i want to modify the loot table of grass to always drop plant fiber but also keep the vanilla drops. Most common answer i have seen is GlobalLootModifiers. But my tiny brain cant understand any tutorials. So any help is appreciated.
    • Minecraft forge 1.12.2 does not load. Here is both logs. I assume its because of a mod that i have, idk. (L521)
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.