Skip to content

Commit

Permalink
even more progress
Browse files Browse the repository at this point in the history
  • Loading branch information
btwonion committed Jun 12, 2024
1 parent 2f949d2 commit f949bae
Show file tree
Hide file tree
Showing 11 changed files with 209 additions and 202 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class ChestBoatMixin {
method = "destroy(Lnet/minecraft/world/damagesource/DamageSource;)V",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/vehicle/VehicleEntity;destroy(Lnet/minecraft/world/item/Item;)V"
target = "Lnet/minecraft/world/entity/vehicle/ChestBoat;destroy(Lnet/minecraft/world/item/Item;)V"
)
)
private void checkForPlayer(
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,69 +1,67 @@
package dev.nyon.telekinesis.mixins;

import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import dev.nyon.telekinesis.TelekinesisPolicy;
import net.minecraft.server.level.ServerLevel;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import dev.nyon.telekinesis.DropEvent;
import dev.nyon.telekinesis.utils.MixinHelper;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.level.storage.loot.LootParams;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import org.apache.commons.lang3.mutable.MutableInt;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArgs;
import org.spongepowered.asm.mixin.injection.invoke.arg.Args;
import org.spongepowered.asm.mixin.injection.ModifyArg;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

@Mixin(LivingEntity.class)
public abstract class LivingEntityMixin {

@Unique
final LivingEntity livingEntity = (LivingEntity) (Object) this;

@WrapWithCondition(
@ModifyExpressionValue(
method = "dropExperience",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/ExperienceOrb;award(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/phys/Vec3;I)V"
target = "Lnet/minecraft/world/entity/LivingEntity;getExperienceReward(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/entity/Entity;)I"
)
)
public boolean redirectExp(
ServerLevel world,
Vec3 pos,
int amount
public int redirectExp(
int original,
Entity entity
) {
final var attacker = livingEntity.getLastAttacker();
if (!(attacker instanceof ServerPlayer serverPlayer)) return true;
if (!(entity instanceof ServerPlayer player)) return original;

boolean hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.ExpDrops,
serverPlayer,
serverPlayer.getMainHandItem(),
player -> PlayerUtils.addExpToPlayer(player, amount)
);

return !hasTelekinesis;
return MixinHelper.modifyExpressionValuePlayerExp(player, original);
}

@ModifyArgs(
@ModifyArg(
method = "dropFromLootTable",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/storage/loot/LootTable;getRandomItems(Lnet/minecraft/world/level/storage/loot/LootParams;JLjava/util/function/Consumer;)V"
)
),
index = 2
)
public void redirectCommonDrops(
Args args,
DamageSource damageSource,
boolean bl
public Consumer<ItemStack> redirectCommonDrops(
LootParams params,
long seed,
Consumer<ItemStack> original
) {
args.<Consumer<ItemStack>>set(2, item -> {
boolean hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.MobDrops, damageSource, player -> {
if (!player.addItem(item)) livingEntity.spawnAtLocation(item);
});
DamageSource source = params.getParamOrNull(LootContextParams.DAMAGE_SOURCE);
if (source == null || !(source.getEntity() instanceof ServerPlayer player)) return original;

return item -> {
ArrayList<ItemStack> mutableList = new ArrayList<>(List.of(item));
DropEvent.INSTANCE.getEvent()
.invoker()
.invoke(mutableList, new MutableInt(0), player, player.getMainHandItem());

if (!hasTelekinesis) livingEntity.spawnAtLocation(item);
});
if (!mutableList.isEmpty()) original.accept(item);
};
}
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
package dev.nyon.telekinesis.mixins;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import dev.nyon.telekinesis.utils.MixinHelper;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.vehicle.MinecartTNT;
import org.spongepowered.asm.mixin.Mixin;

/*? if >1.20.2 {*/
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.item.Item;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
/*?}*/

@Mixin(MinecartTNT.class)
public class MinecartTNTMixin {

/*? if >1.20.2 {*/
@ModifyExpressionValue(
@Unique
private static final ThreadLocal<ServerPlayer> threadLocal = new ThreadLocal<>();

@WrapOperation(
method = "destroy(Lnet/minecraft/world/damagesource/DamageSource;)V",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/vehicle/MinecartTNT;getDropItem()Lnet/minecraft/world/item/Item;"
target = "Lnet/minecraft/world/entity/vehicle/MinecartTNT;destroy(Lnet/minecraft/world/item/Item;)V"
)
)
private Item changeDroppedItem(
Item original,
DamageSource damageSource
private void checkForPlayer(
MinecartTNT instance,
Item dropItem,
Operation<Void> original,
DamageSource source
) {
return EntityUtils.getDropItemInject(original, damageSource);
MixinHelper.prepareVehicleServerPlayer(instance, dropItem, original, source, threadLocal);
}
/*?}*/
}
Original file line number Diff line number Diff line change
@@ -1,91 +1,56 @@
package dev.nyon.telekinesis.mixins;

import dev.nyon.telekinesis.TelekinesisPolicy;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import dev.nyon.telekinesis.utils.MixinHelper;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.RandomSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.animal.Sheep;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ItemLike;
import org.spongepowered.asm.mixin.Final;
import net.minecraft.world.level.block.Block;
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.Redirect;

import java.util.Map;

@Mixin(Sheep.class)
public abstract class SheepMixin {

@Shadow
@Final
private static Map<DyeColor, ItemLike> ITEM_BY_DYE;
@Unique
private final RandomSource random = RandomSource.create();

private static final ThreadLocal<ServerPlayer> threadLocal = new ThreadLocal<>();

@Redirect(
@WrapOperation(
method = "mobInteract",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/animal/Sheep;shear(Lnet/minecraft/sounds/SoundSource;)V"
)
)
public void manipulateWoolDrops(
private void prepareThreadLocalForShearing(
Sheep instance,
SoundSource soundSource,
Player player,
InteractionHand interactionHand
SoundSource source,
Operation<Void> original,
Player _player,
InteractionHand hand
) {
instance.level()
.playSound(null, instance, SoundEvents.SHEEP_SHEAR, soundSource, 1.0F, 1.0F);
instance.setSheared(true);
int i = 1 + random.nextInt(3);

if (!(player instanceof ServerPlayer serverPlayerr)) {
dropAllNormally(i, instance);
return;
}

boolean hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.ShearingDrops,
serverPlayerr,
player.getItemInHand(interactionHand),
serverPlayer -> {
for (int j = 0; j < i; ++j) {
if (!serverPlayer.addItem(new ItemStack(ITEM_BY_DYE.get(instance.getColor()), 1))) {
ItemEntity entity = instance.spawnAtLocation(ITEM_BY_DYE.get(instance.getColor()), 1);
entity.setDeltaMovement(entity.getDeltaMovement()
.add((random.nextFloat() - random.nextFloat()) * 0.1F,
random.nextFloat() * 0.05F,
(random.nextFloat() - random.nextFloat()) * 0.1F
));
}
}
}
);

if (!hasTelekinesis) dropAllNormally(i, instance);
MixinHelper.prepareShearableServerPlayer(instance, source, original, _player, threadLocal);
}

@Unique
void dropAllNormally(
int i,
Sheep instance
) {
for (int j = 0; j < i; ++j) {
ItemEntity entity = instance.spawnAtLocation(ITEM_BY_DYE.get(instance.getColor()), 1);
entity.setDeltaMovement(entity.getDeltaMovement()
.add((random.nextFloat() - random.nextFloat()) * 0.1F,
random.nextFloat() * 0.05F,
(random.nextFloat() - random.nextFloat()) * 0.1F
));
}
@ModifyExpressionValue(
method = "shear",
at = @At(
value = "INVOKE",
target = "Ljava/util/Map;get(Ljava/lang/Object;)Ljava/lang/Object;"
)
)
private Object modifyShearDrops(Object original) {
ServerPlayer player = threadLocal.get();
if (!(original instanceof Block block)) return original;
if (player == null) return original;

if (MixinHelper.wrapWithConditionPlayerItemSingle(player, new ItemStack(block))) return original;
else return ItemStack.EMPTY;
}
}
Original file line number Diff line number Diff line change
@@ -1,46 +1,54 @@
package dev.nyon.telekinesis.mixins;

import dev.nyon.telekinesis.TelekinesisPolicy;
import net.minecraft.sounds.SoundEvents;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import dev.nyon.telekinesis.utils.MixinHelper;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.animal.SnowGolem;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.ItemLike;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.ModifyArg;

@Mixin(SnowGolem.class)
public class SnowGolemMixin {

@Redirect(
@Unique
private static final ThreadLocal<ServerPlayer> threadLocal = new ThreadLocal<>();

@WrapOperation(
method = "mobInteract",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/animal/SnowGolem;shear(Lnet/minecraft/sounds/SoundSource;)V"
)
)
public void manipulateWoolDrops(
private void prepareThreadLocalForShearing(
SnowGolem instance,
SoundSource soundSource,
Player player,
InteractionHand interactionHand
SoundSource source,
Operation<Void> original,
Player _player
) {
instance.level()
.playSound(null, instance, SoundEvents.SNOW_GOLEM_SHEAR, soundSource, 1.0F, 1.0F);
if (!instance.level()
.isClientSide()) {
instance.setPumpkin(false);

ItemStack item = new ItemStack(Items.CARVED_PUMPKIN);
MixinHelper.prepareShearableServerPlayer(instance, source, original, _player, threadLocal);
}

boolean hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.ShearingDrops, player, serverPlayer -> {
if (!serverPlayer.addItem(item)) instance.spawnAtLocation(item, 1.7F);
});
@ModifyArg(
method = "shear",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/item/ItemStack;<init>(Lnet/minecraft/world/level/ItemLike;)V"
)
)
private ItemLike modifyShearDrops(ItemLike original) {
ServerPlayer player = threadLocal.get();
if (player == null) return original;

if (!hasTelekinesis) instance.spawnAtLocation(item, 1.7F);
}
if (MixinHelper.wrapWithConditionPlayerItemSingle(player, new ItemStack(original))) return original;
else return Items.AIR;
}
}
Loading

0 comments on commit f949bae

Please sign in to comment.