diff --git a/patches/api/Add-villager-reputation-API.patch b/patches/api/Add-villager-reputation-API.patch index 6eb59f4313..70828a1a04 100644 --- a/patches/api/Add-villager-reputation-API.patch +++ b/patches/api/Add-villager-reputation-API.patch @@ -13,6 +13,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +package com.destroystokyo.paper.entity.villager; + +import com.google.common.base.Preconditions; ++ ++import java.util.EnumMap; +import java.util.Map; +import org.jetbrains.annotations.NotNull; + @@ -20,26 +22,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * A reputation score for a player on a villager. + */ +public final class Reputation { -+ private static final ReputationType[] REPUTATION_TYPES = ReputationType.values(); // Avoid allocation ++ + @NotNull -+ private final int[] reputation; ++ private final Map reputation; + + public Reputation() { -+ this(new int[REPUTATION_TYPES.length]); ++ this(new EnumMap<>(ReputationType.class)); + } + -+ // Package level to avoid plugins creating reputations with "magic values". -+ Reputation(@NotNull int[] reputation) { -+ this.reputation = reputation; -+ } -+ -+ public Reputation(@NotNull final Map reputation) { -+ this(); ++ public Reputation(@NotNull Map reputation) { + Preconditions.checkNotNull(reputation, "reputation cannot be null"); -+ -+ for (Map.Entry entry : reputation.entrySet()) { -+ setReputation(entry.getKey(), entry.getValue()); -+ } ++ this.reputation = reputation; + } + + /** @@ -50,7 +43,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + */ + public int getReputation(@NotNull ReputationType type) { + Preconditions.checkNotNull(type, "the reputation type cannot be null"); -+ return reputation[type.ordinal()]; ++ return this.reputation.getOrDefault(type, 0); + } + + /** @@ -61,7 +54,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + */ + public void setReputation(@NotNull ReputationType type, int value) { + Preconditions.checkNotNull(type, "the reputation type cannot be null"); -+ reputation[type.ordinal()] = value; ++ this.reputation.put(type, value); ++ } ++ ++ /** ++ * Gets if a reputation value is currently set for a specific {@link ReputationType}. ++ * ++ * @param type The {@link ReputationType type} to check ++ * @return If there is a value for this {@link ReputationType type} set. ++ */ ++ public boolean hasReputationSet(@NotNull ReputationType type) { ++ return this.reputation.containsKey(type); + } +} diff --git a/src/main/java/com/destroystokyo/paper/entity/villager/ReputationType.java b/src/main/java/com/destroystokyo/paper/entity/villager/ReputationType.java diff --git a/patches/server/Add-villager-reputation-API.patch b/patches/server/Add-villager-reputation-API.patch index 4e416025bb..3f28e0020d 100644 --- a/patches/server/Add-villager-reputation-API.patch +++ b/patches/server/Add-villager-reputation-API.patch @@ -4,21 +4,6 @@ Date: Wed, 22 Apr 2020 23:29:20 +0200 Subject: [PATCH] Add villager reputation API -diff --git a/src/main/java/com/destroystokyo/paper/entity/villager/ReputationConstructor.java b/src/main/java/com/destroystokyo/paper/entity/villager/ReputationConstructor.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 ---- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/entity/villager/ReputationConstructor.java -@@ -0,0 +0,0 @@ -+package com.destroystokyo.paper.entity.villager; -+// Must have own package due to package-level constructor. -+ -+public final class ReputationConstructor { -+ // Abuse the package-level constructor. -+ public static Reputation construct(int[] values) { -+ return new Reputation(values); -+ } -+} diff --git a/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java b/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java @@ -38,24 +23,39 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } + + // Paper start - Add villager reputation API -+ private static final com.destroystokyo.paper.entity.villager.ReputationType[] REPUTATION_TYPES = com.destroystokyo.paper.entity.villager.ReputationType.values(); ++ private static final GossipType[] TYPES = GossipType.values(); + public com.destroystokyo.paper.entity.villager.Reputation getPaperReputation() { -+ int[] reputation = new int[REPUTATION_TYPES.length]; -+ reputation[com.destroystokyo.paper.entity.villager.ReputationType.MAJOR_NEGATIVE.ordinal()] = entries.getOrDefault(GossipType.MAJOR_NEGATIVE, 0); -+ reputation[com.destroystokyo.paper.entity.villager.ReputationType.MAJOR_POSITIVE.ordinal()] = entries.getOrDefault(GossipType.MAJOR_POSITIVE, 0); -+ reputation[com.destroystokyo.paper.entity.villager.ReputationType.MINOR_NEGATIVE.ordinal()] = entries.getOrDefault(GossipType.MINOR_NEGATIVE, 0); -+ reputation[com.destroystokyo.paper.entity.villager.ReputationType.MINOR_POSITIVE.ordinal()] = entries.getOrDefault(GossipType.MINOR_POSITIVE, 0); -+ reputation[com.destroystokyo.paper.entity.villager.ReputationType.TRADING.ordinal()] = entries.getOrDefault(GossipType.TRADING, 0); -+ return com.destroystokyo.paper.entity.villager.ReputationConstructor.construct(reputation); ++ Map map = new java.util.EnumMap<>(com.destroystokyo.paper.entity.villager.ReputationType.class); ++ for (Object2IntMap.Entry type : this.entries.object2IntEntrySet()) { ++ map.put(toApi(type.getKey()), type.getIntValue()); ++ } ++ ++ return new com.destroystokyo.paper.entity.villager.Reputation(map); + } + + public void assignFromPaperReputation(com.destroystokyo.paper.entity.villager.Reputation rep) { -+ int val; -+ if ((val = rep.getReputation(com.destroystokyo.paper.entity.villager.ReputationType.MAJOR_NEGATIVE)) != 0) this.entries.put(GossipType.MAJOR_NEGATIVE, val); -+ if ((val = rep.getReputation(com.destroystokyo.paper.entity.villager.ReputationType.MAJOR_POSITIVE)) != 0) this.entries.put(GossipType.MAJOR_POSITIVE, val); -+ if ((val = rep.getReputation(com.destroystokyo.paper.entity.villager.ReputationType.MINOR_NEGATIVE)) != 0) this.entries.put(GossipType.MINOR_NEGATIVE, val); -+ if ((val = rep.getReputation(com.destroystokyo.paper.entity.villager.ReputationType.MINOR_POSITIVE)) != 0) this.entries.put(GossipType.MINOR_POSITIVE, val); -+ if ((val = rep.getReputation(com.destroystokyo.paper.entity.villager.ReputationType.TRADING)) != 0) this.entries.put(GossipType.TRADING, val); ++ for (GossipType type : TYPES) { ++ com.destroystokyo.paper.entity.villager.ReputationType api = toApi(type); ++ ++ if (rep.hasReputationSet(api)) { ++ int reputation = rep.getReputation(api); ++ if (reputation == 0) { ++ this.entries.removeInt(type); ++ } else { ++ this.entries.put(type, reputation); ++ } ++ } ++ } ++ } ++ ++ private static com.destroystokyo.paper.entity.villager.ReputationType toApi(GossipType type) { ++ return switch (type) { ++ case MAJOR_NEGATIVE -> com.destroystokyo.paper.entity.villager.ReputationType.MAJOR_NEGATIVE; ++ case MINOR_NEGATIVE -> com.destroystokyo.paper.entity.villager.ReputationType.MINOR_NEGATIVE; ++ case MINOR_POSITIVE -> com.destroystokyo.paper.entity.villager.ReputationType.MINOR_POSITIVE; ++ case MAJOR_POSITIVE -> com.destroystokyo.paper.entity.villager.ReputationType.MAJOR_POSITIVE; ++ case TRADING -> com.destroystokyo.paper.entity.villager.ReputationType.TRADING; ++ }; + } + // Paper end } @@ -89,7 +89,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public Reputation getReputation(UUID uniqueId) { + net.minecraft.world.entity.ai.gossip.GossipContainer.EntityGossips rep = getHandle().getGossips().getReputations().get(uniqueId); + if (rep == null) { -+ return new Reputation(Maps.newHashMap()); ++ return new Reputation(new java.util.EnumMap<>(com.destroystokyo.paper.entity.villager.ReputationType.class)); + } + + return rep.getPaperReputation();