diff --git a/patches/api/0201-Add-villager-reputation-API.patch b/patches/api/0201-Add-villager-reputation-API.patch index 14c6a88c1..0bf00d913 100644 --- a/patches/api/0201-Add-villager-reputation-API.patch +++ b/patches/api/0201-Add-villager-reputation-API.patch @@ -6,13 +6,15 @@ Subject: [PATCH] Add villager reputation API diff --git a/src/main/java/com/destroystokyo/paper/entity/villager/Reputation.java b/src/main/java/com/destroystokyo/paper/entity/villager/Reputation.java new file mode 100644 -index 0000000000000000000000000000000000000000..1cc9ef255df888cb7dd7f7f2c5014e818d1be613 +index 0000000000000000000000000000000000000000..0a69e21b0b3001c9cc50951b4b8bd593f6fa74be --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/entity/villager/Reputation.java -@@ -0,0 +1,54 @@ +@@ -0,0 +1,57 @@ +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..1cc9ef255df888cb7dd7f7f2c5014e81 + * 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..1cc9ef255df888cb7dd7f7f2c5014e81 + */ + 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..1cc9ef255df888cb7dd7f7f2c5014e81 + */ + 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/0401-Add-villager-reputation-API.patch b/patches/server/0401-Add-villager-reputation-API.patch index 4c3878033..c73d28b41 100644 --- a/patches/server/0401-Add-villager-reputation-API.patch +++ b/patches/server/0401-Add-villager-reputation-API.patch @@ -4,23 +4,8 @@ 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..0f10c333d88f2e1c56a6c7f22d421084adfd3789 ---- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/entity/villager/ReputationConstructor.java -@@ -0,0 +1,9 @@ -+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 7a7c92f1a026116958ad24312df358a703834369..0de65462956fa734b6405614e047161696e596fb 100644 +index 7a7c92f1a026116958ad24312df358a703834369..1e503b075983343d2b12a5a9216fdad879bf1b7c 100644 --- a/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java +++ b/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java @@ -27,7 +27,7 @@ import net.minecraft.util.VisibleForDebug; @@ -32,37 +17,52 @@ index 7a7c92f1a026116958ad24312df358a703834369..0de65462956fa734b6405614e0471616 @VisibleForDebug public Map> getGossipEntries() { -@@ -226,6 +226,28 @@ public class GossipContainer { +@@ -226,6 +226,43 @@ public class GossipContainer { public void remove(GossipType gossipType) { this.entries.removeInt(gossipType); } + + // 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 } static class GossipEntry { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java -index 1a8a49bd269ed52879866ff3853e131d04aa8bba..f0b910df1ee471b4d72d97c6197ab14f2854976e 100644 +index 1a8a49bd269ed52879866ff3853e131d04aa8bba..d1f5e1292246e0fb252d3d3409bbf37cc8166bbc 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java @@ -17,6 +17,13 @@ import org.bukkit.entity.Villager; @@ -89,7 +89,7 @@ index 1a8a49bd269ed52879866ff3853e131d04aa8bba..f0b910df1ee471b4d72d97c6197ab14f + 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();