Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

Implement ProjectileImpactEvent #168

Merged
merged 1 commit into from
Aug 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Minecraft Forge, Patchwork Project
* Copyright (c) 2016-2020, 2019-2020
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package net.minecraftforge.event.entity;

import net.minecraft.entity.Entity;
import net.minecraft.entity.projectile.ExplosiveProjectileEntity;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.entity.thrown.ThrownEntity;
import net.minecraft.util.hit.HitResult;

/**
* This event is fired when a projectile entity impacts something.
*
* <p>Subclasses of this event exist for more specific types of projectile.</p>
*
* <p>This event is fired for all vanilla projectiles by Patchwork.
* Custom projectiles should fire this event via {@link net.patchworkmc.impl.event.entity.EntityEvents}, check the result,
* and cancel the impact if false.</p>
*
* <p>This event is cancelable. When canceled, the impact will not be processed.
* Killing or other handling of the entity after event cancellation is up to the modder.</p>
*
* <p>This event is fired on the {@link net.minecraftforge.common.MinecraftForge#EVENT_BUS}.</p>
*/
public class ProjectileImpactEvent extends EntityEvent {
private final HitResult ray;

public ProjectileImpactEvent(Entity entity, HitResult ray) {
super(entity);
this.ray = ray;
}

@Override
public boolean isCancelable() {
return true;
}

public HitResult getRayTraceResult() {
return ray;
}

public static class Arrow extends ProjectileImpactEvent {
private final ProjectileEntity arrow;

public Arrow(ProjectileEntity arrow, HitResult ray) {
super(arrow, ray);
this.arrow = arrow;
}

public ProjectileEntity getArrow() {
return arrow;
}
}

public static class Fireball extends ProjectileImpactEvent {
private final ExplosiveProjectileEntity fireball;

public Fireball(ExplosiveProjectileEntity fireball, HitResult ray) {
super(fireball, ray);
this.fireball = fireball;
}

public ExplosiveProjectileEntity getFireball() {
return fireball;
}
}

public static class Throwable extends ProjectileImpactEvent {
private final ThrownEntity throwable;

public Throwable(ThrownEntity throwable, HitResult ray) {
super(throwable, ray);
this.throwable = throwable;
}

public ThrownEntity getThrowable() {
return throwable;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import net.minecraftforge.common.extensions.IForgeItem;
import net.minecraftforge.event.entity.EntityEvent;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.entity.ProjectileImpactEvent;
import net.minecraftforge.event.entity.living.AnimalTameEvent;
import net.minecraftforge.event.entity.living.LivingAttackEvent;
import net.minecraftforge.event.entity.living.LivingDamageEvent;
Expand Down Expand Up @@ -56,10 +57,14 @@
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.passive.AnimalEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.ExplosiveProjectileEntity;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.entity.thrown.ThrownEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.HitResult;
import net.minecraft.world.IWorld;
import net.minecraft.world.MobSpawnerLogic;
import net.minecraft.world.World;
Expand Down Expand Up @@ -196,6 +201,22 @@ public static boolean onAnimalTame(AnimalEntity animal, PlayerEntity tamer) {
return MinecraftForge.EVENT_BUS.post(new AnimalTameEvent(animal, tamer));
}

public static boolean onProjectileImpact(Entity entity, HitResult ray) {
return MinecraftForge.EVENT_BUS.post(new ProjectileImpactEvent(entity, ray));
}

public static boolean onProjectileImpact(ProjectileEntity arrow, HitResult ray) {
return MinecraftForge.EVENT_BUS.post(new ProjectileImpactEvent.Arrow(arrow, ray));
}

public static boolean onProjectileImpact(ExplosiveProjectileEntity fireball, HitResult ray) {
return MinecraftForge.EVENT_BUS.post(new ProjectileImpactEvent.Fireball(fireball, ray));
}

public static boolean onProjectileImpact(ThrownEntity throwable, HitResult ray) {
return MinecraftForge.EVENT_BUS.post(new ProjectileImpactEvent.Throwable(throwable, ray));
}

@Override
public void onInitialize() {
UseItemCallback.EVENT.register((player, world, hand) -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Minecraft Forge, Patchwork Project
* Copyright (c) 2016-2020, 2019-2020
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package net.patchworkmc.mixin.event.entity;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

import net.minecraft.entity.projectile.ExplosiveProjectileEntity;
import net.minecraft.util.hit.HitResult;

import net.patchworkmc.impl.event.entity.EntityEvents;

@Mixin(ExplosiveProjectileEntity.class)
public abstract class MixinExplosiveProjectileEntity {
@Shadow
protected abstract void onCollision(HitResult hitResult);

/**
* Mixin to the redirect the onCollision method, to call {@link net.minecraftforge.event.entity.ProjectileImpactEvent}.
*
* <p>Note: In future versions, the @Redirect should be replaced with a @ModifyVariable to the bl flag.</p>
*/
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/projectile/ExplosiveProjectileEntity;onCollision(Lnet/minecraft/util/hit/HitResult;)V"))
private void hookTick(ExplosiveProjectileEntity entity, HitResult hitResult) {
if (!EntityEvents.onProjectileImpact(entity, hitResult)) {
this.onCollision(hitResult);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Minecraft Forge, Patchwork Project
* Copyright (c) 2016-2020, 2019-2020
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package net.patchworkmc.mixin.event.entity;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import net.minecraft.entity.projectile.LlamaSpitEntity;
import net.minecraft.util.hit.HitResult;

import net.patchworkmc.impl.event.entity.EntityEvents;

@Mixin(LlamaSpitEntity.class)
public class MixinLlamaSpitEntity {
/**
* Mixin to the projectile hit method, to call {@link net.minecraftforge.event.entity.ProjectileImpactEvent}.
*
* <p>This will cancel the rest of method_7481 if the forge event pipeline requests it, but a Fabric mod with higher
* priority can still inject into its head.</p>
*
* <p>This mixin is implemented differently from the other onProjectileImpact mixins because there is no check that
* the hit didn't miss before calling onHit, so we need to maintain calls to onHit for missed shots, but still need
* to check that it didn't miss before calling onProjectileImpact.</p>
*/
@Inject(method = "method_7481", at = @At("HEAD"), cancellable = true)
private void hookHit(HitResult hitResult, CallbackInfo callback) {
LlamaSpitEntity entity = (LlamaSpitEntity) (Object) this;

if (EntityEvents.onProjectileImpact(entity, hitResult)) {
callback.cancel();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Minecraft Forge, Patchwork Project
* Copyright (c) 2016-2020, 2019-2020
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package net.patchworkmc.mixin.event.entity;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.util.hit.HitResult;

import net.patchworkmc.impl.event.entity.EntityEvents;

@Mixin(ProjectileEntity.class)
public class MixinProjectileEntity {
/**
* Mixin to the projectile hit method, to call {@link net.minecraftforge.event.entity.ProjectileImpactEvent}.
*
* <p>This will cancel the rest of onHit if the event pipeline requests it, but a Fabric mod with higher
* priority can still inject into its head.</p>
*
* <p>This mixin is implemented differently from the other onProjectileImpact mixins because there is no check that
* the hit didn't miss before calling onHit, so we need to maintain calls to onHit for missed shots, but still need
* to check that it didn't miss before calling onProjectileImpact.</p>
*/
@Inject(method = "onHit(Lnet/minecraft/util/hit/HitResult;)V", at = @At("HEAD"), cancellable = true)
private void hookHit(HitResult hitResult, CallbackInfo callback) {
if (hitResult.getType() != HitResult.Type.MISS) {
ProjectileEntity entity = (ProjectileEntity) (Object) this;

if (EntityEvents.onProjectileImpact(entity, hitResult)) {
callback.cancel();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Minecraft Forge, Patchwork Project
* Copyright (c) 2016-2020, 2019-2020
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package net.patchworkmc.mixin.event.entity;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

import net.minecraft.entity.projectile.ShulkerBulletEntity;
import net.minecraft.util.hit.HitResult;

import net.patchworkmc.impl.event.entity.EntityEvents;

@Mixin(ShulkerBulletEntity.class)
public abstract class MixinShulkerBulletEntity {
@Shadow
protected abstract void onHit(HitResult hitResult);

/**
* Mixin to the redirect the ShulkerBulletEntity hit method, to call {@link net.minecraftforge.event.entity.ProjectileImpactEvent}.
*
* <p>Note: In future versions, the @Redirect should be replaced with a @ModifyVariable to the bl flag.</p>
*/
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/projectile/ShulkerBulletEntity;onHit(Lnet/minecraft/util/hit/HitResult;)V"))
private void hookTick(ShulkerBulletEntity entity, HitResult hitResult) {
if (!EntityEvents.onProjectileImpact(entity, hitResult)) {
this.onHit(hitResult);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Minecraft Forge, Patchwork Project
* Copyright (c) 2016-2020, 2019-2020
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package net.patchworkmc.mixin.event.entity;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

import net.minecraft.entity.thrown.ThrownEntity;
import net.minecraft.util.hit.HitResult;

import net.patchworkmc.impl.event.entity.EntityEvents;

@Mixin(ThrownEntity.class)
public abstract class MixinThrownEntity {
@Shadow
protected abstract void onCollision(HitResult hitResult);

/**
* Mixin to the redirect the ThrownEntity hit method, to call {@link net.minecraftforge.event.entity.ProjectileImpactEvent}.
*
* <p>Note: In future versions, the @Redirect should be replaced with a @ModifyVariable to the bl flag.</p>
*/
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/thrown/ThrownEntity;onCollision(Lnet/minecraft/util/hit/HitResult;)V"))
private void hookTick(ThrownEntity entity, HitResult hitResult) {
if (!EntityEvents.onProjectileImpact(entity, hitResult)) {
this.onCollision(hitResult);
}
}
}
Loading