diff --git a/common/src/main/java/me/shedaniel/architectury/hooks/ExplosionHooks.java b/common/src/main/java/me/shedaniel/architectury/hooks/ExplosionHooks.java new file mode 100644 index 00000000..611e6599 --- /dev/null +++ b/common/src/main/java/me/shedaniel/architectury/hooks/ExplosionHooks.java @@ -0,0 +1,53 @@ +/* + * Copyright 2020 shedaniel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package me.shedaniel.architectury.hooks; + +import me.shedaniel.architectury.ArchitecturyPopulator; +import me.shedaniel.architectury.Populatable; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Explosion; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; + +@Environment(EnvType.CLIENT) +public final class ExplosionHooks { + private ExplosionHooks() {} + + @Populatable + private static final Impl IMPL = null; + + public static Vec3 getPosition(Explosion explosion) { + return IMPL.getPosition(explosion); + } + + @Nullable + public static Entity getSource(Explosion explosion) { + return IMPL.getSource(explosion); + } + + public interface Impl { + Vec3 getPosition(Explosion explosion); + + Entity getSource(Explosion explosion); + } + + static { + ArchitecturyPopulator.populate(ExplosionHooks.class); + } +} diff --git a/fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/ExplosionHooksImpl.java b/fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/ExplosionHooksImpl.java new file mode 100644 index 00000000..22e316c1 --- /dev/null +++ b/fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/ExplosionHooksImpl.java @@ -0,0 +1,40 @@ +/* + * Copyright 2020 shedaniel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package me.shedaniel.architectury.hooks.fabric; + +import me.shedaniel.architectury.hooks.ExplosionHooks; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Explosion; +import net.minecraft.world.phys.Vec3; + +public class ExplosionHooksImpl implements ExplosionHooks.Impl { + @Override + public Vec3 getPosition(Explosion explosion) { + return ((ExplosionExtensions) explosion).architectury_getPosition(); + } + + @Override + public Entity getSource(Explosion explosion) { + return ((ExplosionExtensions) explosion).architectury_getSource(); + } + + public interface ExplosionExtensions { + Vec3 architectury_getPosition(); + + Entity architectury_getSource(); + } +} diff --git a/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/MixinExplosion.java b/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/MixinExplosion.java index 2c7d3453..8200acd1 100644 --- a/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/MixinExplosion.java +++ b/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/MixinExplosion.java @@ -17,13 +17,17 @@ package me.shedaniel.architectury.mixin.fabric; import me.shedaniel.architectury.event.events.ExplosionEvent; +import me.shedaniel.architectury.hooks.fabric.ExplosionHooksImpl; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -33,11 +37,30 @@ import java.util.List; import java.util.Set; @Mixin(Explosion.class) -public class MixinExplosion { +public class MixinExplosion implements ExplosionHooksImpl.ExplosionExtensions { @Shadow @Final private Level level; + @Shadow @Final private double x; + @Shadow @Final private double y; + @Shadow @Final private double z; + @Shadow @Final @Nullable private Entity source; + @Unique Vec3 position; - @Inject(method = "explode", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/phys/Vec3;(DDD)V", ordinal = 0), locals = LocalCapture.CAPTURE_FAILHARD) + @Inject(method = "explode", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/phys/Vec3;(DDD)V", ordinal = 0), + locals = LocalCapture.CAPTURE_FAILHARD) private void explodePost(CallbackInfo ci, Set set, float q, int r, int s, int t, int u, int v, int w, List list) { ExplosionEvent.DETONATE.invoker().explode(level, (Explosion) (Object) this, list); } + + @Override + public Vec3 architectury_getPosition() { + if (position == null) { + return position = new Vec3(x, y, z); + } + return position; + } + + @Override + public Entity architectury_getSource() { + return source; + } } diff --git a/forge/src/main/java/me/shedaniel/architectury/hooks/forge/ExplosionHooksImpl.java b/forge/src/main/java/me/shedaniel/architectury/hooks/forge/ExplosionHooksImpl.java new file mode 100644 index 00000000..ba0cddb4 --- /dev/null +++ b/forge/src/main/java/me/shedaniel/architectury/hooks/forge/ExplosionHooksImpl.java @@ -0,0 +1,34 @@ +/* + * Copyright 2020 shedaniel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package me.shedaniel.architectury.hooks.forge; + +import me.shedaniel.architectury.hooks.ExplosionHooks; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.Explosion; + +public class ExplosionHooksImpl implements ExplosionHooks.Impl { + @Override + public Vector3d getPosition(Explosion explosion) { + return explosion.getPosition(); + } + + @Override + public Entity getSource(Explosion explosion) { + return explosion.getExploder(); + } +}