Skip to content

Commit

Permalink
The great Mixin bazaar.
Browse files Browse the repository at this point in the history
Revalidates some Trade and villager related trades by finding their targets.
  • Loading branch information
i509VCB committed Dec 14, 2019
1 parent f0bf039 commit 9b1aff8
Show file tree
Hide file tree
Showing 13 changed files with 154 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,20 @@
*/
package org.spongepowered.common.item.util;

import net.minecraft.item.MerchantOffer;
import net.minecraft.village.MerchantRecipe;
import org.spongepowered.api.item.merchant.TradeOffer;

public class TradeOfferUtil {

public static MerchantRecipe toNative(TradeOffer tradeOffer) {
if (tradeOffer instanceof MerchantRecipe) {
return (MerchantRecipe) tradeOffer;
public static MerchantOffer toNative(TradeOffer tradeOffer) {
if (tradeOffer instanceof MerchantOffer) {
return (MerchantOffer) tradeOffer;
}
throw new NativeTradeOfferException("The supplied trade offer was not native to the current platform");
}

public static TradeOffer fromNative(MerchantRecipe merchantRecipe) {
public static TradeOffer fromNative(MerchantOffer merchantRecipe) {
if (merchantRecipe instanceof TradeOffer || merchantRecipe == null) {
return (TradeOffer) merchantRecipe;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,10 @@

import static com.google.common.base.Preconditions.checkNotNull;

import net.minecraft.entity.merchant.villager.VillagerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.village.MerchantRecipe;
import net.minecraft.item.MerchantOffer;
import org.spongepowered.api.item.merchant.Merchant;
import org.spongepowered.api.item.merchant.TradeOffer;
import org.spongepowered.api.item.merchant.TradeOfferGenerator;
Expand All @@ -44,23 +43,25 @@
// added as the only thing needing to be done is a simple default implementation
// with an empty MerchantRecipeList and diff the list with an empty one and
// provide the resulting diff'ed MerchantRecipe (TradeOffer) as the result.
@Mixin(VillagerEntity.EmeraldForItems.class)
public class EntityVillager_EmeraldForItemsMixin_API implements TradeOfferGenerator {
//
// i509VCB: Yes the classes which implement ITrade, like ItemsForEmeraldsAndItemsTrade are package private
// For clarification this trade is multiple Items -> 1 Emerald
// TODO: These need a new home
@Mixin(targets = "net/minecraft/entity/merchant/villager/VillagerTrades$EmeraldForItemsTrade")
public class VillagerTrades_EmeraldForItemsTradeMixin_API implements TradeOfferGenerator {

@Shadow public Item buyingItem;
@Shadow public VillagerEntity.PriceInfo price;
@Shadow public Item tradeItem;
@Shadow public int count; // Amount of item required to receive an emerald
@Shadow public int maxUses;
@Shadow public int xpValue;
@Shadow public float priceMultiplier;

@Override
public TradeOffer apply(Random random) {
checkNotNull(random, "Random cannot be null!");
int buyingCount = 1;

if (this.price != null) {
buyingCount = this.price.getPrice(random);
}

final ItemStack buyingItem = new ItemStack(this.buyingItem, buyingCount, 0);
return (TradeOffer) new MerchantRecipe(buyingItem, Items.EMERALD);
final ItemStack buyingItem = new ItemStack(this.tradeItem, count);
return (TradeOffer) new MerchantOffer(buyingItem, new ItemStack(Items.EMERALD), maxUses, xpValue, priceMultiplier);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@
import static com.google.common.base.Preconditions.checkNotNull;

import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.merchant.villager.VillagerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.village.MerchantRecipe;
import net.minecraft.item.MerchantOffer;
import org.spongepowered.api.item.merchant.Merchant;
import org.spongepowered.api.item.merchant.TradeOffer;
import org.spongepowered.api.item.merchant.TradeOfferGenerator;
Expand All @@ -44,25 +43,27 @@
// added as the only thing needing to be done is a simple default implementation
// with an empty MerchantRecipeList and diff the list with an empty one and
// provide the resulting diff'ed MerchantRecipe (TradeOffer) as the result.
@Mixin(VillagerEntity.ListEnchantedItemForEmeralds.class)
public class EntityVillager_ListEnchantedItemForEmeraldsMixin_API implements TradeOfferGenerator {
//
// i509VCB: Yes the classes which implement ITrade, like ItemsForEmeraldsAndItemsTrade are package private
// For clarification this trade is Emeralds -> Enchanted Item
// TODO: These need a new home
@Mixin(targets = "net/minecraft/entity/merchant/villager/VillagerTrades$EnchantedItemForEmeraldsTrade")
public class VillagerTrades_EnchantItemForEmeraldsTrade_API implements TradeOfferGenerator {

@Shadow public ItemStack enchantedItemStack;
@Shadow public VillagerEntity.PriceInfo priceInfo;
@Shadow public ItemStack sellingStack; // Note this is not enchanted yet.
@Shadow public int emeraldCount;
@Shadow public int maxUses;
@Shadow public int xpValue;
@Shadow public float priceMultiplier;

@Override
public TradeOffer apply(Random random) {
checkNotNull(random, "Random cannot be null!");
int emeraldCount = 1;

if (this.priceInfo != null) {
emeraldCount = this.priceInfo.getPrice(random);
}

ItemStack itemstack = new ItemStack(Items.EMERALD, emeraldCount, 0);
ItemStack itemstack1 = new ItemStack(this.enchantedItemStack.getItem(), 1, this.enchantedItemStack.getMetadata());
itemstack1 = EnchantmentHelper.addRandomEnchantment(random, itemstack1, 5 + random.nextInt(15), false);
return (TradeOffer) new MerchantRecipe(itemstack, itemstack1);
ItemStack emeraldItemStack = new ItemStack(Items.EMERALD, emeraldCount);
ItemStack enchantedItemStack = new ItemStack(this.sellingStack.getItem(), 1);
enchantedItemStack.setTag(this.sellingStack.getTag().copy());
enchantedItemStack = EnchantmentHelper.addRandomEnchantment(random, enchantedItemStack, 5 + random.nextInt(15), false);
return (TradeOffer) new MerchantOffer(emeraldItemStack, enchantedItemStack, maxUses, xpValue, priceMultiplier);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,17 @@

import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentData;
import net.minecraft.entity.merchant.villager.VillagerEntity;
import net.minecraft.item.EnchantedBookItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.item.MerchantOffer;
import net.minecraft.util.math.MathHelper;
import net.minecraft.village.MerchantRecipe;
import net.minecraft.util.registry.Registry;
import org.spongepowered.api.item.merchant.Merchant;
import org.spongepowered.api.item.merchant.TradeOffer;
import org.spongepowered.api.item.merchant.TradeOfferGenerator;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;

import java.util.List;
import java.util.Random;
Expand All @@ -46,13 +47,18 @@
// added as the only thing needing to be done is a simple default implementation
// with an empty MerchantRecipeList and diff the list with an empty one and
// provide the resulting diff'ed MerchantRecipe (TradeOffer) as the result.
@Mixin(VillagerEntity.ListEnchantedBookForEmeralds.class)
public class EntityVillager_ListEnchantedBookForEmeraldsMixin_API implements TradeOfferGenerator {
//
// i509VCB: Yes the classes which implement ITrade, like ItemsForEmeraldsAndItemsTrade are package private
// For clarification this trade is Emeralds + Book -> Enchanted Book
// TODO: These need a new home
@Mixin(targets = "net/minecraft/entity/merchant/villager/VillagerTrades$EnchantedBookForEmeraldsTrade")
public class VillagerTrades_EnchantedBookForEmeraldsTradeMixin_API implements TradeOfferGenerator {
@Shadow int xpValue;

@Override
public TradeOffer apply(Random random) {
checkNotNull(random, "Random cannot be null!");
Enchantment enchantment = Enchantment.REGISTRY.getRandom(random);
Enchantment enchantment = Registry.ENCHANTMENT.getRandom(random);
int enchantmentLevel = MathHelper.nextInt(random, enchantment.getMinLevel(), enchantment.getMaxLevel());
ItemStack itemstack = EnchantedBookItem.getEnchantedItemStack(new EnchantmentData(enchantment, enchantmentLevel));
int emeraldCount = 2 + random.nextInt(5 + enchantmentLevel * 10) + 3 * enchantmentLevel;
Expand All @@ -64,8 +70,8 @@ public TradeOffer apply(Random random) {
if (emeraldCount > 64) {
emeraldCount = 64;
}

return (TradeOffer) new MerchantRecipe(new ItemStack(Items.BOOK), new ItemStack(Items.EMERALD, emeraldCount), itemstack);
// Vanilla seems to hardcode the max uses to 12 and a multiplier of 0.2
return (TradeOffer) new MerchantOffer(new ItemStack(Items.BOOK), new ItemStack(Items.EMERALD, emeraldCount), itemstack, 12, this.xpValue, 0.2F);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@

import static com.google.common.base.Preconditions.checkNotNull;

import net.minecraft.entity.merchant.villager.VillagerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.village.MerchantRecipe;
import net.minecraft.item.MerchantOffer;
import org.spongepowered.api.item.merchant.Merchant;
import org.spongepowered.api.item.merchant.TradeOffer;
import org.spongepowered.api.item.merchant.TradeOfferGenerator;
Expand All @@ -43,33 +42,33 @@
// added as the only thing needing to be done is a simple default implementation
// with an empty MerchantRecipeList and diff the list with an empty one and
// provide the resulting diff'ed MerchantRecipe (TradeOffer) as the result.
@Mixin(VillagerEntity.ItemAndEmeraldToItem.class)
public class EntityVillager_ItemAndEmeraldToItemMixin_API implements TradeOfferGenerator {
//
// i509VCB: Yes the classes which implement ITrade, like ItemsForEmeraldsAndItemsTrade are package private
// For clarification this trade is Emeralds + Item(s) -> A related item.
// This is similar to the Raw Cod + Emeralds -> Cooked Cod trade.
// TODO: These need a new home
@Mixin(targets = "net/minecraft/entity/merchant/villager/VillagerTrades$ItemsForEmeraldsAndItemsTrade")
public class VillagerTrades_ItemsForEmeraldsAndItemsTrade_API implements TradeOfferGenerator {

@Shadow public ItemStack buyingItemStack;
@Shadow public VillagerEntity.PriceInfo buyingPriceInfo;
@Shadow public ItemStack sellingItemstack;
@Shadow public VillagerEntity.PriceInfo sellingPriceInfo;
@Shadow private ItemStack buyingItem;
@Shadow private int buyingItemCount;
@Shadow private int emeraldCount;
@Shadow private ItemStack sellingItem;
@Shadow private int sellingItemCount;
@Shadow private int maxUses;
@Shadow private int xpValue;
@Shadow private float priceMultiplier;

@Override
public TradeOffer apply(Random random) {
checkNotNull(random, "Random cannot be null!");
int buyingCount = 1;

if (this.buyingPriceInfo != null) {
buyingCount = this.buyingPriceInfo.getPrice(random);
}

int sellingCount = 1;

if (this.sellingPriceInfo != null) {
sellingCount = this.sellingPriceInfo.getPrice(random);
}

final ItemStack itemStackBuying = new ItemStack(this.buyingItemStack.getItem(), buyingCount, this.buyingItemStack.getMetadata());
final ItemStack emeraldStack = new ItemStack(Items.EMERALD);
final ItemStack itemStackSelling = new ItemStack(this.sellingItemstack.getItem(), sellingCount, this.sellingItemstack.getMetadata());
return (TradeOffer) new MerchantRecipe(itemStackBuying, emeraldStack, itemStackSelling);
final ItemStack itemStackBuying = new ItemStack(this.buyingItem.getItem(), buyingItemCount);
itemStackBuying.setTag(this.buyingItem.getTag().copy());
final ItemStack emeraldStack = new ItemStack(Items.EMERALD, emeraldCount);
final ItemStack itemStackSelling = new ItemStack(this.sellingItem.getItem(), sellingItemCount);
itemStackSelling.setTag(sellingItem.getTag().copy());
return (TradeOffer) new MerchantOffer(itemStackBuying, emeraldStack, itemStackSelling, maxUses, xpValue, priceMultiplier);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@

import static com.google.common.base.Preconditions.checkNotNull;

import net.minecraft.entity.merchant.villager.VillagerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.village.MerchantRecipe;
import net.minecraft.item.MerchantOffer;
import org.spongepowered.api.item.merchant.Merchant;
import org.spongepowered.api.item.merchant.TradeOffer;
import org.spongepowered.api.item.merchant.TradeOfferGenerator;
Expand All @@ -43,33 +42,36 @@
// added as the only thing needing to be done is a simple default implementation
// with an empty MerchantRecipeList and diff the list with an empty one and
// provide the resulting diff'ed MerchantRecipe (TradeOffer) as the result.
@Mixin(VillagerEntity.ListItemForEmeralds.class)
public class EntityVillager_ListItemForEmeraldsMixin_API implements TradeOfferGenerator {

@Shadow public ItemStack itemToBuy;
@Shadow public VillagerEntity.PriceInfo priceInfo;
//
// i509VCB: Yes the classes which implement ITrade, like ItemsForEmeraldsAndItemsTrade are package private
// For clarification this trade is Emeralds -> Item(s) such as a generic Emeralds -> Bread trade.\
// TODO: These need a new home
@Mixin(targets = "net/minecraft/entity/merchant/villager/VillagerTrades$ItemsForEmeraldsTrade")
public class VillagerTrades_ItemsForEmeraldsTrade_API implements TradeOfferGenerator {
@Shadow public ItemStack field_221208_a; // Item being sold to the customer
@Shadow public int emeraldCount; // Amount of emeralds required to be bought.
@Shadow public int field_221210_c; // Amount of item sold
@Shadow public int field_221211_d; // Max uses
@Shadow public int field_221212_e; // Exp rewarded from trade
@Shadow public float field_221213_f; // Price multiplier

@Override
public TradeOffer apply(Random random) {
checkNotNull(random, "Random cannot be null!");
int amount = 1;

if (this.priceInfo != null) {
amount = this.priceInfo.getPrice(random);
}

ItemStack itemstack;
ItemStack itemstack1;
ItemStack emeraldItemStack;
ItemStack sellingItem;

if (amount < 0) {
itemstack = new ItemStack(Items.EMERALD, 1, 0);
itemstack1 = new ItemStack(this.itemToBuy.getItem(), -amount, this.itemToBuy.getMetadata());
if (emeraldCount < 0) {
emeraldItemStack = new ItemStack(Items.EMERALD);
sellingItem = new ItemStack(this.field_221208_a.getItem(), -field_221210_c);
sellingItem.setTag(this.field_221208_a.getTag().copy());
} else {
itemstack = new ItemStack(Items.EMERALD, amount, 0);
itemstack1 = new ItemStack(this.itemToBuy.getItem(), 1, this.itemToBuy.getMetadata());
emeraldItemStack = new ItemStack(Items.EMERALD, emeraldCount);
sellingItem = new ItemStack(this.field_221208_a.getItem(), 1);
sellingItem.setTag(this.field_221208_a.getTag().copy());
}

return (TradeOffer) new MerchantRecipe(itemstack, itemstack1);
return (TradeOffer) new MerchantOffer(emeraldItemStack, sellingItem, field_221211_d, field_221212_e, field_221213_f);
}


Expand Down

0 comments on commit 9b1aff8

Please sign in to comment.