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

Commit dc6fe55

Browse files
authored
Add EntityItemPickupEvent and EntityTravelToDimensionEvent (#179)
* Add EntityItemPickupEvent (It should really be named ItemEntityPickupEvent but w/e) * Add EntityTravelToDimensionEvent * Fix checkstyle * Add Forge behavioural change w.r.t teleporting `StorageMinecartEntity`s
1 parent c2edb12 commit dc6fe55

File tree

11 files changed

+253
-3
lines changed

11 files changed

+253
-3
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.minecraftforge.event.entity;
21+
22+
import net.minecraftforge.common.MinecraftForge;
23+
24+
import net.minecraft.entity.Entity;
25+
import net.minecraft.world.dimension.DimensionType;
26+
27+
/**
28+
* <p>EntityTravelToDimensionEvent is fired before an Entity travels to a dimension.</p>
29+
*
30+
* <p>{@link #dimension} contains the id of the dimension the entity is traveling to.</p>
31+
*
32+
* <p>This event is cancelable.
33+
* If this event is canceled, the Entity does not travel to the dimension.</p>
34+
*
35+
* <p>This event does not have a result.</p>
36+
*
37+
* <p>This event is fired on the {@link MinecraftForge#EVENT_BUS}.</p>
38+
*/
39+
public class EntityTravelToDimensionEvent extends EntityEvent {
40+
private final DimensionType dimension;
41+
42+
public EntityTravelToDimensionEvent(Entity entity, DimensionType dimension) {
43+
super(entity);
44+
this.dimension = dimension;
45+
}
46+
47+
public DimensionType getDimension() {
48+
return dimension;
49+
}
50+
51+
@Override
52+
public boolean isCancelable() {
53+
return true;
54+
}
55+
}
56+
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.minecraftforge.event.entity.player;
21+
22+
import net.minecraft.entity.ItemEntity;
23+
import net.minecraft.entity.player.PlayerEntity;
24+
25+
/**
26+
* <p>This event is called when a player collides with a EntityItem on the ground.
27+
* The event can be canceled, and no further processing will be done.</p>
28+
*
29+
* <p>You can set the result of this event to ALLOW which will trigger the
30+
* processing of achievements, FML's event, play the sound, and kill the
31+
* entity if all the items are picked up.</p>
32+
*
33+
* <p>setResult(ALLOW) is the same as the old setHandled()</p>
34+
*/
35+
public class EntityItemPickupEvent extends PlayerEvent {
36+
private final ItemEntity item;
37+
38+
public EntityItemPickupEvent(PlayerEntity player, ItemEntity item) {
39+
super(player);
40+
this.item = item;
41+
}
42+
43+
public ItemEntity getItem() {
44+
return item;
45+
}
46+
47+
@Override
48+
public boolean isCancelable() {
49+
return true;
50+
}
51+
52+
@Override
53+
public boolean hasResult() {
54+
return true;
55+
}
56+
}

patchwork-events-entity/src/main/java/net/patchworkmc/impl/event/entity/EntityEvents.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import net.minecraftforge.common.extensions.IForgeItem;
2727
import net.minecraftforge.event.entity.EntityEvent;
2828
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
29+
import net.minecraftforge.event.entity.EntityTravelToDimensionEvent;
2930
import net.minecraftforge.event.entity.ProjectileImpactEvent;
3031
import net.minecraftforge.event.entity.living.AnimalTameEvent;
3132
import net.minecraftforge.event.entity.living.LivingAttackEvent;
@@ -60,6 +61,7 @@
6061
import net.minecraft.entity.projectile.ExplosiveProjectileEntity;
6162
import net.minecraft.entity.projectile.ProjectileEntity;
6263
import net.minecraft.entity.thrown.ThrownEntity;
64+
import net.minecraft.entity.vehicle.StorageMinecartEntity;
6365
import net.minecraft.item.ItemStack;
6466
import net.minecraft.text.Text;
6567
import net.minecraft.util.ActionResult;
@@ -68,11 +70,14 @@
6870
import net.minecraft.world.IWorld;
6971
import net.minecraft.world.MobSpawnerLogic;
7072
import net.minecraft.world.World;
73+
import net.minecraft.world.dimension.DimensionType;
7174

7275
import net.fabricmc.api.ModInitializer;
7376
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
7477
import net.fabricmc.fabric.api.event.player.UseItemCallback;
7578

79+
import net.patchworkmc.mixin.event.entity.StorageMinecartEntityAccessor;
80+
7681
public class EntityEvents implements ModInitializer {
7782
private static final Logger LOGGER = LogManager.getLogger("patchwork-events-entity");
7883

@@ -217,6 +222,21 @@ public static boolean onProjectileImpact(ThrownEntity throwable, HitResult ray)
217222
return MinecraftForge.EVENT_BUS.post(new ProjectileImpactEvent.Throwable(throwable, ray));
218223
}
219224

225+
public static boolean onTravelToDimension(Entity entity, DimensionType dimensionType) {
226+
EntityTravelToDimensionEvent event = new EntityTravelToDimensionEvent(entity, dimensionType);
227+
boolean result = !MinecraftForge.EVENT_BUS.post(event);
228+
229+
if (!result) {
230+
// Revert variable back to true as it would have been set to false
231+
232+
if (entity instanceof StorageMinecartEntity) {
233+
((StorageMinecartEntityAccessor) entity).dropContentsWhenDead(true);
234+
}
235+
}
236+
237+
return result;
238+
}
239+
220240
@Override
221241
public void onInitialize() {
222242
UseItemCallback.EVENT.register((player, world, hand) -> {

patchwork-events-entity/src/main/java/net/patchworkmc/impl/event/entity/PlayerEvents.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
package net.patchworkmc.impl.event.entity;
2121

2222
import net.minecraftforge.common.MinecraftForge;
23+
import net.minecraftforge.event.entity.player.EntityItemPickupEvent;
2324
import net.minecraftforge.event.entity.player.PlayerEvent;
25+
import net.minecraftforge.eventbus.api.Event;
2426

2527
import net.minecraft.entity.ItemEntity;
2628
import net.minecraft.entity.player.PlayerEntity;
@@ -56,4 +58,14 @@ public static void firePlayerCraftingEvent(PlayerEntity player, ItemStack crafte
5658
public static void firePlayerSmeltedEvent(PlayerEntity player, ItemStack smelted) {
5759
MinecraftForge.EVENT_BUS.post(new PlayerEvent.ItemSmeltedEvent(player, smelted));
5860
}
61+
62+
/**
63+
*
64+
* @return -1 if the event was cancelled, 0 if the event was denied, 1 if the event was accepted
65+
*/
66+
public static int onItemPickup(PlayerEntity player, ItemEntity entityItem) {
67+
Event event = new EntityItemPickupEvent(player, entityItem);
68+
if (MinecraftForge.EVENT_BUS.post(event)) return -1;
69+
return event.getResult() == Event.Result.ALLOW ? 1 : 0;
70+
}
5971
}

patchwork-events-entity/src/main/java/net/patchworkmc/mixin/event/entity/MixinEntity.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424
import org.spongepowered.asm.mixin.injection.At;
2525
import org.spongepowered.asm.mixin.injection.Inject;
2626
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
27+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
2728

2829
import net.minecraft.entity.Entity;
2930
import net.minecraft.entity.EntityDimensions;
3031
import net.minecraft.entity.EntityPose;
3132
import net.minecraft.entity.EntityType;
3233
import net.minecraft.world.World;
34+
import net.minecraft.world.dimension.DimensionType;
3335

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

@@ -52,4 +54,14 @@ public void hookConstructor(EntityType<?> type, World world, CallbackInfo ci) {
5254

5355
EntityEvents.onEntityConstruct(entity);
5456
}
57+
58+
@Inject(method = "changeDimension",
59+
at = @At("HEAD"),
60+
cancellable = true
61+
)
62+
void patchwork_fireTravelToDimensionEventChangeDimension(DimensionType newDimension, CallbackInfoReturnable<Entity> cir) {
63+
if (!EntityEvents.onTravelToDimension((Entity) (Object) this, newDimension)) {
64+
cir.setReturnValue(null);
65+
}
66+
}
5567
}

patchwork-events-entity/src/main/java/net/patchworkmc/mixin/event/entity/MixinItemEntity.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@
2121

2222
import org.spongepowered.asm.mixin.Mixin;
2323
import org.spongepowered.asm.mixin.injection.At;
24+
import org.spongepowered.asm.mixin.injection.At.Shift;
2425
import org.spongepowered.asm.mixin.injection.Inject;
26+
import org.spongepowered.asm.mixin.injection.Redirect;
2527
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
26-
import org.spongepowered.asm.mixin.injection.At.Shift;
2728

2829
import net.minecraft.entity.ItemEntity;
2930
import net.minecraft.entity.player.PlayerEntity;
31+
import net.minecraft.entity.player.PlayerInventory;
32+
import net.minecraft.item.ItemStack;
3033

3134
import net.patchworkmc.impl.event.entity.PlayerEvents;
3235

@@ -44,4 +47,22 @@ private void onPlayerPickUpItemEntity(PlayerEntity player, CallbackInfo ci) {
4447
ItemEntity me = (ItemEntity) (Object) this;
4548
PlayerEvents.firePlayerItemPickupEvent(player, me, me.getStack().copy());
4649
}
50+
51+
int eventResult;
52+
53+
@Inject(method = "onPlayerCollision",
54+
at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getCount()I"),
55+
cancellable = true
56+
)
57+
void patchwork_fireItemPickupEvent(PlayerEntity player, CallbackInfo ci) {
58+
eventResult = PlayerEvents.onItemPickup(player, (ItemEntity) (Object) this);
59+
if (eventResult != 1) ci.cancel();
60+
}
61+
62+
@Redirect(method = "onPlayerCollision",
63+
at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerInventory;insertStack(Lnet/minecraft/item/ItemStack;)Z")
64+
)
65+
boolean patchwork_skipIfEventNotAllowed(PlayerInventory playerInventory, ItemStack stack) {
66+
return eventResult == 1 || playerInventory.insertStack(stack);
67+
}
4768
}

patchwork-events-entity/src/main/java/net/patchworkmc/mixin/event/entity/MixinServerPlayerEntity.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package net.patchworkmc.mixin.event.entity;
2121

22+
import com.mojang.authlib.GameProfile;
2223
import net.minecraftforge.common.MinecraftForge;
2324
import net.minecraftforge.event.entity.player.PlayerEvent;
2425
import org.spongepowered.asm.mixin.Mixin;
@@ -33,16 +34,22 @@
3334
import net.minecraft.entity.Entity;
3435
import net.minecraft.entity.LivingEntity;
3536
import net.minecraft.entity.damage.DamageSource;
37+
import net.minecraft.entity.player.PlayerEntity;
3638
import net.minecraft.server.network.ServerPlayerEntity;
3739
import net.minecraft.server.world.ServerWorld;
40+
import net.minecraft.world.World;
3841
import net.minecraft.world.dimension.DimensionType;
3942
import net.minecraft.world.level.LevelProperties;
4043

4144
import net.patchworkmc.impl.event.entity.EntityEvents;
4245
import net.patchworkmc.impl.event.entity.PlayerEvents;
4346

4447
@Mixin(ServerPlayerEntity.class)
45-
public class MixinServerPlayerEntity {
48+
public abstract class MixinServerPlayerEntity extends PlayerEntity {
49+
public MixinServerPlayerEntity(World world, GameProfile profile) {
50+
super(world, profile);
51+
}
52+
4653
@Inject(method = "onDeath", at = @At("HEAD"), cancellable = true)
4754
private void hookDeath(DamageSource source, CallbackInfo callback) {
4855
LivingEntity entity = (LivingEntity) (Object) this;
@@ -59,6 +66,19 @@ private void hookCopyFromForCloneEvent(ServerPlayerEntity oldPlayer, boolean ali
5966
MinecraftForge.EVENT_BUS.post(new PlayerEvent.Clone(speThis, oldPlayer, !alive));
6067
}
6168

69+
@Inject(method = "teleport",
70+
at = @At(
71+
value = "INVOKE",
72+
target = "Lnet/minecraft/server/network/ServerPlayerEntity;getServerWorld()Lnet/minecraft/server/world/ServerWorld;"
73+
),
74+
cancellable = true
75+
)
76+
void patchwork_fireTravelToDimensionEventTeleport(ServerWorld targetWorld, double x, double y, double z, float yaw, float pitch, CallbackInfo ci) {
77+
if (!EntityEvents.onTravelToDimension(this, targetWorld.dimension.getType())) {
78+
ci.cancel();
79+
}
80+
}
81+
6282
////////////////////////////////////
6383
// PlayerChangedDimensionEvent
6484
////////////////////////////////////
@@ -79,6 +99,16 @@ private void teleport_sendInventory(ServerWorld targetWorld, double x, double y,
7999
@Unique
80100
private static final ThreadLocal<DimensionType> changeDimension_from = new ThreadLocal<>();
81101

102+
@Inject(method = "changeDimension",
103+
at = @At("HEAD"),
104+
cancellable = true
105+
)
106+
void patchwork_fireTravelToDimensionEventChangeDimensionPlayer(DimensionType newDimension, CallbackInfoReturnable<Entity> cir) {
107+
if (!EntityEvents.onTravelToDimension(this, newDimension)) {
108+
cir.setReturnValue(null);
109+
}
110+
}
111+
82112
@Inject(method = "changeDimension",
83113
at = @At(
84114
value = "INVOKE",
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.patchworkmc.mixin.event.entity;
21+
22+
import org.spongepowered.asm.mixin.Mixin;
23+
import org.spongepowered.asm.mixin.gen.Accessor;
24+
25+
import net.minecraft.entity.vehicle.StorageMinecartEntity;
26+
27+
@Mixin(StorageMinecartEntity.class)
28+
public interface StorageMinecartEntityAccessor {
29+
@Accessor("field_7733")
30+
void dropContentsWhenDead(boolean value);
31+
}

patchwork-events-entity/src/main/resources/patchwork-events-entity.mixins.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
"MixinShulkerBulletEntity",
2626
"MixinSpawnHelper",
2727
"MixinThrownEntity",
28-
"MixinWorldChunk"
28+
"MixinWorldChunk",
29+
"StorageMinecartEntityAccessor"
2930
],
3031
"client": [
3132
"MixinClientPlayerEntity",

patchwork-god-classes/src/main/java/net/minecraftforge/common/ForgeHooks.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import net.minecraftforge.event.ForgeEventFactory;
2929
import net.minecraftforge.eventbus.api.Event;
3030

31+
import net.minecraft.world.dimension.DimensionType;
3132
import net.minecraft.entity.Entity;
3233
import net.minecraft.entity.ItemEntity;
3334
import net.minecraft.entity.LivingEntity;
@@ -110,6 +111,10 @@ public static boolean onPlayerAttackTarget(PlayerEntity player, Entity target) {
110111
return EntityEvents.attackEntity(player, target);
111112
}
112113

114+
public static boolean onTravelToDimension(Entity entity, DimensionType dimensionType) {
115+
return EntityEvents.onTravelToDimension(entity, dimensionType);
116+
}
117+
113118
public static int onBlockBreakEvent(World world, GameMode gameType, ServerPlayerEntity entityPlayer, BlockPos pos) {
114119
return BlockHarvestManager.onBlockBreakEvent(world, gameType, entityPlayer, pos);
115120
}

0 commit comments

Comments
 (0)