Fix updating villager trade experience (#3906)

* Fix villager experience not updating

Remove unnecessary fake trade experience stuff

* Hide trade level for wandering traders
This commit is contained in:
Amberichu 2023-06-22 17:38:05 -04:00 committed by GitHub
parent 50d7f56aaf
commit 70db98eeaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 14 deletions

View File

@ -67,10 +67,6 @@ public class SessionPlayerEntity extends PlayerEntity {
*/ */
@Getter @Getter
private boolean isRidingInFront; private boolean isRidingInFront;
/**
* Used for villager inventory emulation.
*/
private int fakeTradeXp;
public SessionPlayerEntity(GeyserSession session) { public SessionPlayerEntity(GeyserSession session) {
super(session, -1, 1, null, Vector3f.ZERO, Vector3f.ZERO, 0, 0, 0, null, null); super(session, -1, 1, null, Vector3f.ZERO, Vector3f.ZERO, 0, 0, 0, null, null);
@ -175,11 +171,6 @@ public class SessionPlayerEntity extends PlayerEntity {
this.isRidingInFront = position != null && position.getX() > 0; this.isRidingInFront = position != null && position.getX() > 0;
} }
public void addFakeTradeExperience(int tradeXp) {
fakeTradeXp += tradeXp;
dirtyMetadata.put(EntityDataTypes.TRADE_EXPERIENCE, fakeTradeXp);
}
@Override @Override
public AttributeData createHealthAttribute() { public AttributeData createHealthAttribute() {
// Max health must be divisible by two in bedrock // Max health must be divisible by two in bedrock

View File

@ -30,6 +30,7 @@ import com.github.steveice10.mc.protocol.data.game.inventory.VillagerTrade;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.Entity;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@ -40,6 +41,8 @@ public class MerchantContainer extends Container {
private VillagerTrade[] villagerTrades; private VillagerTrade[] villagerTrades;
@Getter @Setter @Getter @Setter
private ClientboundMerchantOffersPacket pendingOffersPacket; private ClientboundMerchantOffersPacket pendingOffersPacket;
@Getter @Setter
private int tradeExperience;
public MerchantContainer(String title, int id, int size, ContainerType containerType, PlayerInventory playerInventory) { public MerchantContainer(String title, int id, int size, ContainerType containerType, PlayerInventory playerInventory) {
super(title, id, size, containerType, playerInventory); super(title, id, size, containerType, playerInventory);
@ -49,9 +52,10 @@ public class MerchantContainer extends Container {
if (villagerTrades != null && slot >= 0 && slot < villagerTrades.length) { if (villagerTrades != null && slot >= 0 && slot < villagerTrades.length) {
VillagerTrade trade = villagerTrades[slot]; VillagerTrade trade = villagerTrades[slot];
setItem(2, GeyserItemStack.from(trade.getOutput()), session); setItem(2, GeyserItemStack.from(trade.getOutput()), session);
// TODO this logic doesn't add up
session.getPlayerEntity().addFakeTradeExperience(trade.getXp()); tradeExperience += trade.getXp();
session.getPlayerEntity().updateBedrockMetadata(); villager.getDirtyMetadata().put(EntityDataTypes.TRADE_EXPERIENCE, tradeExperience);
villager.updateBedrockMetadata();
} }
} }
} }

View File

@ -73,9 +73,17 @@ public class JavaMerchantOffersTranslator extends PacketTranslator<ClientboundMe
public static void openMerchant(GeyserSession session, ClientboundMerchantOffersPacket packet, MerchantContainer merchantInventory) { public static void openMerchant(GeyserSession session, ClientboundMerchantOffersPacket packet, MerchantContainer merchantInventory) {
// Retrieve the fake villager involved in the trade, and update its metadata to match with the window information // Retrieve the fake villager involved in the trade, and update its metadata to match with the window information
merchantInventory.setVillagerTrades(packet.getTrades()); merchantInventory.setVillagerTrades(packet.getTrades());
merchantInventory.setTradeExperience(packet.getExperience());
Entity villager = merchantInventory.getVillager(); Entity villager = merchantInventory.getVillager();
villager.getDirtyMetadata().put(EntityDataTypes.TRADE_TIER, packet.getVillagerLevel() - 1); if (packet.isRegularVillager()) {
villager.getDirtyMetadata().put(EntityDataTypes.MAX_TRADE_TIER, 4); villager.getDirtyMetadata().put(EntityDataTypes.TRADE_TIER, packet.getVillagerLevel() - 1);
villager.getDirtyMetadata().put(EntityDataTypes.MAX_TRADE_TIER, 4);
} else {
// Don't show trade level for wandering traders
villager.getDirtyMetadata().put(EntityDataTypes.TRADE_TIER, 0);
villager.getDirtyMetadata().put(EntityDataTypes.MAX_TRADE_TIER, 0);
}
villager.getDirtyMetadata().put(EntityDataTypes.TRADE_EXPERIENCE, packet.getExperience()); villager.getDirtyMetadata().put(EntityDataTypes.TRADE_EXPERIENCE, packet.getExperience());
villager.updateBedrockMetadata(); villager.updateBedrockMetadata();