Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-25 15:50:14 +01:00
Fix villager prices with demand price adjustments (#2767)
* Fix villager prices with demand price adjustments * Don't cap second input/output item count * Handle negative item counts properly * Don't get item mapping twice * Add null check to getItemTag
Dieser Commit ist enthalten in:
Ursprung
da33811e3b
Commit
36afd3f2ec
@ -43,6 +43,7 @@ import org.geysermc.geyser.session.GeyserSession;
|
|||||||
import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
|
import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.Translator;
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
|
import org.geysermc.geyser.util.MathUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -99,16 +100,17 @@ public class JavaMerchantOffersTranslator extends PacketTranslator<ClientboundMe
|
|||||||
recipe.putInt("maxUses", trade.isTradeDisabled() ? 0 : trade.getMaxUses());
|
recipe.putInt("maxUses", trade.isTradeDisabled() ? 0 : trade.getMaxUses());
|
||||||
recipe.putInt("traderExp", trade.getXp());
|
recipe.putInt("traderExp", trade.getXp());
|
||||||
recipe.putFloat("priceMultiplierA", trade.getPriceMultiplier());
|
recipe.putFloat("priceMultiplierA", trade.getPriceMultiplier());
|
||||||
recipe.put("sell", getItemTag(session, trade.getOutput(), 0));
|
|
||||||
recipe.putFloat("priceMultiplierB", 0.0f);
|
recipe.putFloat("priceMultiplierB", 0.0f);
|
||||||
recipe.putInt("buyCountB", trade.getSecondInput() != null ? trade.getSecondInput().getAmount() : 0);
|
recipe.put("sell", getItemTag(session, trade.getOutput()));
|
||||||
recipe.putInt("buyCountA", trade.getFirstInput().getAmount());
|
|
||||||
recipe.putInt("demand", trade.getDemand());
|
// The buy count before demand and special price adjustments
|
||||||
|
recipe.putInt("buyCountA", Math.max(trade.getFirstInput().getAmount(), 0));
|
||||||
|
recipe.putInt("buyCountB", trade.getSecondInput() != null ? Math.max(trade.getSecondInput().getAmount(), 0) : 0);
|
||||||
|
|
||||||
|
recipe.putInt("demand", trade.getDemand()); // Seems to have no effect
|
||||||
recipe.putInt("tier", packet.getVillagerLevel() > 0 ? packet.getVillagerLevel() - 1 : 0); // -1 crashes client
|
recipe.putInt("tier", packet.getVillagerLevel() > 0 ? packet.getVillagerLevel() - 1 : 0); // -1 crashes client
|
||||||
recipe.put("buyA", getItemTag(session, trade.getFirstInput(), trade.getSpecialPrice()));
|
recipe.put("buyA", getItemTag(session, trade.getFirstInput(), trade.getSpecialPrice(), trade.getDemand(), trade.getPriceMultiplier()));
|
||||||
if (trade.getSecondInput() != null) {
|
recipe.put("buyB", getItemTag(session, trade.getSecondInput()));
|
||||||
recipe.put("buyB", getItemTag(session, trade.getSecondInput(), 0));
|
|
||||||
}
|
|
||||||
recipe.putInt("uses", trade.getNumUses());
|
recipe.putInt("uses", trade.getNumUses());
|
||||||
recipe.putByte("rewardExp", (byte) 1);
|
recipe.putByte("rewardExp", (byte) 1);
|
||||||
tags.add(recipe.build());
|
tags.add(recipe.build());
|
||||||
@ -144,12 +146,31 @@ public class JavaMerchantOffersTranslator extends PacketTranslator<ClientboundMe
|
|||||||
session.sendUpstreamPacket(updateTradePacket);
|
session.sendUpstreamPacket(updateTradePacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NbtMap getItemTag(GeyserSession session, ItemStack stack, int specialPrice) {
|
private static NbtMap getItemTag(GeyserSession session, ItemStack stack) {
|
||||||
ItemData itemData = ItemTranslator.translateToBedrock(session, stack);
|
if (stack == null || stack.getAmount() <= 0) { // Negative item counts appear as air on Java
|
||||||
|
return NbtMap.EMPTY;
|
||||||
|
}
|
||||||
|
return getItemTag(session, stack, session.getItemMappings().getMapping(stack), stack.getAmount());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NbtMap getItemTag(GeyserSession session, ItemStack stack, int specialPrice, int demand, float priceMultiplier) {
|
||||||
|
if (stack == null || stack.getAmount() <= 0) { // Negative item counts appear as air on Java
|
||||||
|
return NbtMap.EMPTY;
|
||||||
|
}
|
||||||
ItemMapping mapping = session.getItemMappings().getMapping(stack);
|
ItemMapping mapping = session.getItemMappings().getMapping(stack);
|
||||||
|
|
||||||
|
// Bedrock expects all price adjustments to be applied to the item's count
|
||||||
|
int count = stack.getAmount() + ((int) Math.max(Math.floor(stack.getAmount() * demand * priceMultiplier), 0)) + specialPrice;
|
||||||
|
count = MathUtils.constrain(count, 1, mapping.getStackSize());
|
||||||
|
|
||||||
|
return getItemTag(session, stack, mapping, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NbtMap getItemTag(GeyserSession session, ItemStack stack, ItemMapping mapping, int count) {
|
||||||
|
ItemData itemData = ItemTranslator.translateToBedrock(session, stack);
|
||||||
|
|
||||||
NbtMapBuilder builder = NbtMap.builder();
|
NbtMapBuilder builder = NbtMap.builder();
|
||||||
builder.putByte("Count", (byte) (Math.max(itemData.getCount() + specialPrice, 1)));
|
builder.putByte("Count", (byte) count);
|
||||||
builder.putShort("Damage", (short) itemData.getDamage());
|
builder.putShort("Damage", (short) itemData.getDamage());
|
||||||
builder.putString("Name", mapping.getBedrockIdentifier());
|
builder.putString("Name", mapping.getBedrockIdentifier());
|
||||||
if (itemData.getTag() != null) {
|
if (itemData.getTag() != null) {
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren